手机进销存管理系统--04实现框架基础页面

一、在我们实现框架页面之前,我们先来做另外两件工作:

  1. 日志记录,引入log4j的jar包,创建log4j.properties文件手机进销存管理系统--04实现框架基础页面
    log4j.appender.console=org.apache.log4j.ConsoleAppender
    log4j.appender.console.layout=org.apache.log4j.SimpleLayout
    log4j.rootCategory=DEBUG, console
  2. 在web.xml文件中配置Spring的字符过滤器--对用户的请求以及服务器发出的响应的URL的编码进行转换,否则当用户发送的请求包含中文时,比如表单提交时用户名输入为中文,容易出现乱码现象。但是Spring的这个字符过滤器最好配置在其它过滤器之前。
    	<!-- Spring字符过滤器 -->
    	<filter>
    		<filter-name>CharsetFilter</filter-name>
    		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    		<init-param>
    			<param-name>encoding</param-name>
    			<param-value>utf-8</param-value>
    		</init-param>
    	</filter>
    	<filter-mapping>
    		<filter-name>CharsetFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>

二、框架页面实现

  1. 我们希望用户在访问我们系统时,页面的title总是显示我们系统的名称--手机进销存管理系统,如那么我们可以自定义一个监听器SysInitListener,在系统启动的时候通过读取配置文件,然后将系统名称放到application中,我们就可以通过EL表达式在页面上获取,web.xml配置如下
    	<context-param>
    		<param-name>sysname</param-name>
    		<param-value>
    			手机进销存管理系统
    		</param-value>
    	</context-param>
    	<!-- 自定义的系统初始化监听器 -->
    	<listener>
    		<listener-class>com.mobile.utils.SysInitListener</listener-class>
    	</listener>
    自定义的监听器SysInitListener的代码非常简单,如下:
    public class SysInitListener implements ServletContextListener {
    
    	@Override
    	public void contextDestroyed(ServletContextEvent arg0) {
    		// TODO Auto-generated method stub
    
    	}
    
    	@Override
    	public void contextInitialized(ServletContextEvent event) {
    
    		ServletContext application = event.getServletContext();
    		String sysname = application.getInitParameter("sysname");
    		application.setAttribute("sysname", sysname);
    	}
    
    }
  2. 系统登录验证码生成类--ValidateCodeGenerator.java
    public class ValidateCodeGenerator {
    	
    	//用于生成验证码的字符数组
        final private char[] chars = "2345678ABCDEFGHJKLMPQRSTUVWXYabcdefhkmnqrstuvwx"
                .toCharArray();
        //验证码的字符字体
        private static String[] fontNames = new String[] { "Courier", "Arial",
                "Verdana", "Georgia", "Times", "Tahoma" };
        //字符样式
        private static int[] fontStyle = new int[] { Font.PLAIN, Font.BOLD,
                Font.ITALIC, Font.BOLD | Font.ITALIC };
    
        private int width = 160;			//验证码图片宽度
        private int height = 60;			//验证码图片高度
        private int charCnt = 4;			//验证码图片字符数
        private int disturbLineNum = 10;	//干扰线条数
    
        private OutputStream os;
    
        public ValidateCodeGenerator(OutputStream os) {
            this.os = os;
        }
    
        public ValidateCodeGenerator(OutputStream os, int width, int height, int charCnt) {
            this.width = width;
            this.height = height;
            this.charCnt = charCnt;
            this.os = os;
        }
    
        /**
         * 画验证码图片
         * @return
         * @throws IOException
         */
        public String drawCode() throws IOException {
        	//验证码图片
            BufferedImage bi = new BufferedImage(this.width, this.height,
                    BufferedImage.TYPE_INT_RGB);
            //图片画笔
            Graphics2D g = bi.createGraphics();
            //用画笔设置不骗颜色
            g.setColor(new Color(245, 245, 245));
            g.fillRect(0, 0, this.width, this.height);
    
            //画干扰线
            drawDisturbLine(g);
    
            //在验证码大图片的基础上生成四个小的图片,用于存放生成的单个验证码字符
            BufferedImage[] bis = new BufferedImage[charCnt];
            //生成字符
            char[] codes = generateCode();
            for (int i = 0; i < charCnt; i++) {
                bis[i] = generateBuffImg(codes[i]);
                g.drawImage(bis[i], null, (int) (this.height * 0.62) * i, 0);
            }
    
            g.dispose();
    
            ImageIO.write(bi, "gif", os);
            return new String(codes);
        }
    
        /**
         * 将生成的每个字符放到图片上,也就是在我们整个验证码大图片上,生成的验证码字符其实是四个小图片
         * @param c
         * @return
         */
        private BufferedImage generateBuffImg(char c) {
            String tmp = Character.toString(c);
            Color forecolor = getRandomColor();
            Color backcolor = new Color(255, 255, 255, 0);
            String fontName = getRandomFontName();
            int fontStyle = getRandomStyle();
            int fontSize = getRandomSize();
            int strX = (this.height - fontSize) / 2;
            int strY = (this.height - fontSize) / 2 + fontSize;
            //设置字符旋转的角度
            double arch = getRandomArch();
    
            BufferedImage ret = new BufferedImage(this.height, this.height,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = ret.createGraphics();
            g.setColor(backcolor);
            g.fillRect(0, 0, this.height, this.height);
    
            g.setColor(forecolor);
            g.setFont(new Font(fontName, fontStyle, fontSize));
            g.rotate(arch, this.height / 2, this.height / 2);
            //在生成的小图片上画生成字符串,其实就是我们生成的单个字符
            g.drawString(tmp, strX, strY);
    
            g.dispose();
            return ret;
        }
    
        private double getRandomArch() {
            return ((int) (Math.random() * 1000) % 2 == 0 ? -1 : 1) * Math.random();
        }
    
        private Color getRandomColor() {
            int r = (int) (Math.random() * 10000) % 200;
            int g = (int) (Math.random() * 10000) % 200;
            int b = (int) (Math.random() * 10000) % 200;
            return new Color(r, g, b);
        }
    
        private String getRandomFontName() {
            int pos = (int) (Math.random() * 10000) % (fontNames.length);
            return fontNames[pos];
        }
    
        private int getRandomStyle() {
            int pos = (int) (Math.random() * 10000) % (fontStyle.length);
            return fontStyle[pos];
        }
    
        private int getRandomSize() {
            int max = (int) (this.height * 0.98);
            int min = (int) (this.height * 0.75);
            return (int) (Math.random() * 10000) % (max - min + 1) + min;
        }
    
        /**
         * 生成验证码字符方法
         * @return
         */
        private char[] generateCode() {
        	//用于存放生成字符的数组
            char[] ret = new char[charCnt];
            for (int i = 0; i < charCnt; i++) {
                int letterPos = (int) (Math.random() * 10000) % (chars.length);
                ret[i] = chars[letterPos];
            }
            return ret;
        }
    
        /**
         * 画干扰线
         * @param graphics--画笔
         */
        private void drawDisturbLine(Graphics2D graphics) {
            for (int i = 0; i < disturbLineNum; i++) {
            	//随机获取干扰线颜色
                graphics.setColor(getRandomColor());
                int x = (int) (Math.random() * 10000) % (this.width + 1) + 1;
                int x1 = (int) (Math.random() * 10000) % (this.width + 1) + 1;
                int y = (int) (Math.random() * 10000) % (this.height + 1) + 1;
                int y1 = (int) (Math.random() * 10000) % (this.height + 1) + 1;
                graphics.drawLine(x, y, x1, y1);
            }
    
        }
    
        public static void main(String[] args) throws IOException {
            FileOutputStream fos = new FileOutputStream("d:/Space/tmp/tmp.gif");
            ValidateCodeGenerator vg = new ValidateCodeGenerator(fos);
            vg.drawCode();
        }
    }
    创建一个Servlet,用于当用户请求系统时,调用ValidateCodeGenerator生成验证码,并将验证码存放到Session中,以便在页面获取;另外当用户想更换验证码时,可以点击验证码图片跟换另一个验证码,使用AJAX请求,但是之前我们将验证码放到Session中,如果不是一个新的请求,会直接从Session中获取,那么就无法实现验证码图片的更换,所以我们在每个请求加上一个时间,可以当用户想更换图片时,服务器就会认为是一个新的请求,从而实现验证码的更换。

你可能感兴趣的:(手机进销存管理系统--04实现框架基础页面)