Ver Código Fonte

图片验证的工具类和配置文件。

zzy.zhiyuan.foxmail 8 anos atrás
pai
commit
bc6faa2c0d

+ 42 - 0
src/main/java/com/ekexiu/portal/util/PictureVC.java

@ -0,0 +1,42 @@
1
package com.ekexiu.portal.util;
2

3
import java.io.IOException;  
4

5
import javax.servlet.Servlet;
6
import javax.servlet.ServletException;  
7
import javax.servlet.http.Cookie;
8
import javax.servlet.http.HttpServlet;
9
import javax.servlet.http.HttpServletRequest;  
10
import javax.servlet.http.HttpServletResponse;  
11

12
public class PictureVC extends HttpServlet implements Servlet {  
13
  
14
	private static final long serialVersionUID = 2459158903781864570L;
15

16
	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
17
        response.setHeader("Pragma", "No-cache");  
18
        response.setHeader("Cache-Control", "no-cache");  
19
        response.setDateHeader("Expires", 0);  
20
        response.setContentType("image/jpeg");  
21
          
22
        //生成随机字串  
23
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
24
        //获取上次请求发送的rand的cookie 设置生命为0.
25
        Cookie[] cookies = request.getCookies();
26
        for (Cookie cookie : cookies) {
27
			if("rand".equalsIgnoreCase(cookie.getName())){
28
				cookie.setMaxAge(0);
29
			}
30
		}
31
        //为随机数创建cookie
32
        Cookie rand = new Cookie("rand", verifyCode.toLowerCase());
33
        //设置cookie中随机数的过期时间为1小时
34
        rand.setMaxAge(60 * 60);
35
        //在响应头中添加cookie
36
        response.addCookie(rand);
37
        //生成图片  
38
        int w = 100, h = 40;  
39
        VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);  
40
  
41
    }  
42
} 

+ 268 - 0
src/main/java/com/ekexiu/portal/util/VerifyCodeUtils.java

@ -0,0 +1,268 @@
1
package com.ekexiu.portal.util;
2

3
import java.awt.Color;  
4
import java.awt.Font;  
5
import java.awt.Graphics;  
6
import java.awt.Graphics2D;  
7
import java.awt.RenderingHints;  
8
import java.awt.geom.AffineTransform;  
9
import java.awt.image.BufferedImage;  
10
import java.io.File;  
11
import java.io.FileOutputStream;  
12
import java.io.IOException;  
13
import java.io.OutputStream;  
14
import java.util.Arrays;  
15
import java.util.Random;  
16
  
17
import javax.imageio.ImageIO;  
18
  
19
public class VerifyCodeUtils{  
20
  
21
    //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符  
22
    public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";  
23
    private static Random random = new Random();  
24
  
25
  
26
    /** 
27
     * 使用系统默认字符源生成验证码 
28
     * @param verifySize    验证码长度 
29
     * @return 
30
     */  
31
    public static String generateVerifyCode(int verifySize){  
32
        return generateVerifyCode(verifySize, VERIFY_CODES);  
33
    }  
34
    /** 
35
     * 使用指定源生成验证码 
36
     * @param verifySize    验证码长度 
37
     * @param sources   验证码字符源 
38
     * @return 
39
     */  
40
    public static String generateVerifyCode(int verifySize, String sources){  
41
        if(sources == null || sources.length() == 0){  
42
            sources = VERIFY_CODES;  
43
        }  
44
        int codesLen = sources.length();  
45
        Random rand = new Random(System.currentTimeMillis());  
46
        StringBuilder verifyCode = new StringBuilder(verifySize);  
47
        for(int i = 0; i < verifySize; i++){  
48
            verifyCode.append(sources.charAt(rand.nextInt(codesLen-1)));  
49
        }  
50
        return verifyCode.toString();  
51
    }  
52
      
53
    /** 
54
     * 生成随机验证码文件,并返回验证码值 
55
     * @param w 
56
     * @param h 
57
     * @param outputFile 
58
     * @param verifySize 
59
     * @return 
60
     * @throws IOException 
61
     */  
62
    public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{  
63
        String verifyCode = generateVerifyCode(verifySize);  
64
        outputImage(w, h, outputFile, verifyCode);  
65
        return verifyCode;  
66
    }  
67
      
68
    /** 
69
     * 输出随机验证码图片流,并返回验证码值 
70
     * @param w 
71
     * @param h 
72
     * @param os 
73
     * @param verifySize 
74
     * @return 
75
     * @throws IOException 
76
     */  
77
    public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{  
78
        String verifyCode = generateVerifyCode(verifySize);  
79
        outputImage(w, h, os, verifyCode);  
80
        return verifyCode;  
81
    }  
82
      
83
    /** 
84
     * 生成指定验证码图像文件 
85
     * @param w 
86
     * @param h 
87
     * @param outputFile 
88
     * @param code 
89
     * @throws IOException 
90
     */  
91
    public static void outputImage(int w, int h, File outputFile, String code) throws IOException{  
92
        if(outputFile == null){  
93
            return;  
94
        }  
95
        File dir = outputFile.getParentFile();  
96
        if(!dir.exists()){  
97
            dir.mkdirs();  
98
        }  
99
        try{  
100
            outputFile.createNewFile();  
101
            FileOutputStream fos = new FileOutputStream(outputFile);  
102
            outputImage(w, h, fos, code);  
103
            fos.close();  
104
        } catch(IOException e){  
105
            throw e;  
106
        }  
107
    }  
108
      
109
    /** 
110
     * 输出指定验证码图片流 
111
     * @param w 
112
     * @param h 
113
     * @param os 
114
     * @param code 
115
     * @throws IOException 
116
     */  
117
    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{  
118
        int verifySize = code.length();  
119
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
120
        Random rand = new Random();  
121
        Graphics2D g2 = image.createGraphics();  
122
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);  
123
        Color[] colors = new Color[5];  
124
        Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN,  
125
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,  
126
                Color.PINK, Color.YELLOW };  
127
        float[] fractions = new float[colors.length];  
128
        for(int i = 0; i < colors.length; i++){  
129
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];  
130
            fractions[i] = rand.nextFloat();  
131
        }  
132
        Arrays.sort(fractions);  
133
          
134
        g2.setColor(Color.GRAY);// 设置边框色  
135
        g2.fillRect(0, 0, w, h);  
136
          
137
        Color c = getRandColor(200, 250);  
138
        g2.setColor(c);// 设置背景色  
139
        g2.fillRect(0, 2, w, h-4);  
140
          
141
        //绘制干扰线  
142
        Random random = new Random();  
143
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色  
144
        for (int i = 0; i < 20; i++) {  
145
            int x = random.nextInt(w - 1);  
146
            int y = random.nextInt(h - 1);  
147
            int xl = random.nextInt(6) + 1;  
148
            int yl = random.nextInt(12) + 1;  
149
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);  
150
        }  
151
          
152
        // 添加噪点  
153
        float yawpRate = 0.05f;// 噪声率  
154
        int area = (int) (yawpRate * w * h);  
155
        for (int i = 0; i < area; i++) {  
156
            int x = random.nextInt(w);  
157
            int y = random.nextInt(h);  
158
            int rgb = getRandomIntColor();  
159
            image.setRGB(x, y, rgb);  
160
        }  
161
          
162
        shear(g2, w, h, c);// 使图片扭曲  
163
  
164
        g2.setColor(getRandColor(100, 160));  
165
        int fontSize = h-4;  
166
        Font font = new Font("Algerian", Font.ITALIC, fontSize);  
167
        g2.setFont(font);  
168
        char[] chars = code.toCharArray();  
169
        for(int i = 0; i < verifySize; i++){  
170
            AffineTransform affine = new AffineTransform();  
171
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2);  
172
            g2.setTransform(affine);  
173
            g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10);  
174
        }  
175
          
176
        g2.dispose();  
177
        ImageIO.write(image, "jpg", os);  
178
    }  
179
      
180
    private static Color getRandColor(int fc, int bc) {  
181
        if (fc > 255)  
182
            fc = 255;  
183
        if (bc > 255)  
184
            bc = 255;  
185
        int r = fc + random.nextInt(bc - fc);  
186
        int g = fc + random.nextInt(bc - fc);  
187
        int b = fc + random.nextInt(bc - fc);  
188
        return new Color(r, g, b);  
189
    }  
190
      
191
    private static int getRandomIntColor() {  
192
        int[] rgb = getRandomRgb();  
193
        int color = 0;  
194
        for (int c : rgb) {  
195
            color = color << 8;  
196
            color = color | c;  
197
        }  
198
        return color;  
199
    }  
200
      
201
    private static int[] getRandomRgb() {  
202
        int[] rgb = new int[3];  
203
        for (int i = 0; i < 3; i++) {  
204
            rgb[i] = random.nextInt(255);  
205
        }  
206
        return rgb;  
207
    }  
208
  
209
    private static void shear(Graphics g, int w1, int h1, Color color) {  
210
        shearX(g, w1, h1, color);  
211
        shearY(g, w1, h1, color);  
212
    }  
213
      
214
    private static void shearX(Graphics g, int w1, int h1, Color color) {  
215
  
216
        int period = random.nextInt(2);  
217
  
218
        boolean borderGap = true;  
219
        int frames = 1;  
220
        int phase = random.nextInt(2);  
221
  
222
        for (int i = 0; i < h1; i++) {  
223
            double d = (double) (period >> 1)  
224
                    * Math.sin((double) i / (double) period  
225
                            + (6.2831853071795862D * (double) phase)  
226
                            / (double) frames);  
227
            g.copyArea(0, i, w1, 1, (int) d, 0);  
228
            if (borderGap) {  
229
                g.setColor(color);  
230
                g.drawLine((int) d, i, 0, i);  
231
                g.drawLine((int) d + w1, i, w1, i);  
232
            }  
233
        }  
234
  
235
    }  
236
  
237
    private static void shearY(Graphics g, int w1, int h1, Color color) {  
238
  
239
        int period = random.nextInt(40) + 10; // 50;  
240
  
241
        boolean borderGap = true;  
242
        int frames = 20;  
243
        int phase = 7;  
244
        for (int i = 0; i < w1; i++) {  
245
            double d = (double) (period >> 1)  
246
                    * Math.sin((double) i / (double) period  
247
                            + (6.2831853071795862D * (double) phase)  
248
                            / (double) frames);  
249
            g.copyArea(i, 0, 1, h1, 0, (int) d);  
250
            if (borderGap) {  
251
                g.setColor(color);  
252
                g.drawLine(i, (int) d, i, 0);  
253
                g.drawLine(i, (int) d + h1, i, h1);  
254
            }  
255
  
256
        }  
257
  
258
    }
259
    
260
//    //测试main函数,输出验证图片到指定路径
261
//    public static void main(String[] args) throws IOException{  
262
//        File dir = new File("F:/verifies");  
263
//        int w = 200, h = 80;  
264
//        String verifyCode = generateVerifyCode(4);  
265
//        File file = new File(dir, verifyCode + ".jpg");  
266
//        outputImage(w, h, file, verifyCode);  
267
//    }  
268
}  

+ 9 - 0
src/main/webapp/WEB-INF/web.xml

@ -36,6 +36,11 @@
36 36
  	<servlet-class>com.ekexiu.portal.util.FileDownload</servlet-class>
37 37
  	<load-on-startup>4</load-on-startup>
38 38
  </servlet>
39
  <servlet>
40
  	<servlet-name>PictureVC</servlet-name>
41
  	<servlet-class>com.ekexiu.portal.util.PictureVC</servlet-class>
42
  	<load-on-startup>5</load-on-startup>
43
  </servlet>
39 44
  
40 45
  <servlet-mapping>
41 46
    <servlet-name>ajax</servlet-name>
@ -53,4 +58,8 @@
53 58
    <servlet-name>FileDownload</servlet-name>
54 59
    <url-pattern>/ajax/FileDownload</url-pattern>
55 60
  </servlet-mapping>
61
  <servlet-mapping>
62
    <servlet-name>PictureVC</servlet-name>
63
    <url-pattern>/ajax/PictureVC</url-pattern>
64
  </servlet-mapping>
56 65
</web-app>