生成验证码

  1 /**
  2  * 
  3  */
  4 package org.jeecgframework.web.system.servlet;
  5 
  6 import org.jeecgframework.core.util.ResourceUtil;
  7 
  8 import java.awt.Color;
  9 import java.awt.Font;
 10 import java.awt.Graphics2D;
 11 import java.awt.image.BufferedImage;
 12 import java.io.IOException;
 13 import java.util.Random;
 14 
 15 import javax.imageio.ImageIO;
 16 import javax.servlet.ServletException;
 17 import javax.servlet.http.HttpServlet;
 18 import javax.servlet.http.HttpServletRequest;
 19 import javax.servlet.http.HttpServletResponse;
 20 
 21 
 22 /**
 23  * 随机生成验证图片
 24  * 
 25  * 
 26  */
 27 public class RandCodeImageServlet extends HttpServlet {
 28     private static final long serialVersionUID = -1257947018545327308L;
 29     private static final String SESSION_KEY_OF_RAND_CODE = "randCode"; // todo 要统一常量
 30     /**
 31      * 
 32      */
 33     private static final int count = 200;
 34 
 35     /**
 36      * 定义图形大小
 37      */
 38     private static final int width = 105;
 39     /**
 40      * 定义图形大小
 41      */
 42     private static final int height = 35;
 43     // private Font mFont = new Font("Arial Black", Font.PLAIN, 15); //设置字体
 44     /**
 45      * 干扰线的长度=1.414*lineWidth
 46      */
 47     private static final int lineWidth = 2;
 48 
 49     @Override
 50     public void doGet(final HttpServletRequest request,
 51             final HttpServletResponse response) throws ServletException,
 52             IOException {
 53         // 设置页面不缓存
 54         response.setHeader("Pragma", "No-cache");
 55         response.setHeader("Cache-Control", "no-cache");
 56         response.setDateHeader("Expires", 0);
 57         // response.setContentType("image/png");
 58 
 59         // 在内存中创建图象
 60         final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 61         // 获取图形上下文
 62         final Graphics2D graphics = (Graphics2D) image.getGraphics();
 63 
 64         // 设定背景颜色
 65         graphics.setColor(Color.WHITE); // ---1
 66         graphics.fillRect(0, 0, width, height);
 67         // 设定边框颜色
 68 //        graphics.setColor(getRandColor(100, 200)); // ---2
 69         graphics.drawRect(0, 0, width - 1, height - 1);
 70 
 71         final Random random = new Random();
 72         // 随机产生干扰线,使图象中的认证码不易被其它程序探测到
 73         for (int i = 0; i < count; i++) {
 74             graphics.setColor(getRandColor(150, 200)); // ---3
 75 
 76             final int x = random.nextInt(width - lineWidth - 1) + 1; // 保证画在边框之内
 77             final int y = random.nextInt(height - lineWidth - 1) + 1;
 78             final int xl = random.nextInt(lineWidth);
 79             final int yl = random.nextInt(lineWidth);
 80             graphics.drawLine(x, y, x + xl, y + yl);
 81         }
 82 
 83         // 取随机产生的认证码(4位数字)
 84         final String resultCode = exctractRandCode();
 85         for (int i = 0; i < resultCode.length(); i++) {
 86             // 将认证码显示到图象中,调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
 87             // graphics.setColor(new Color(20 + random.nextInt(130), 20 + random
 88             // .nextInt(130), 20 + random.nextInt(130)));
 89 
 90             // 设置字体颜色
 91             graphics.setColor(Color.BLACK);
 92             // 设置字体样式
 93 //            graphics.setFont(new Font("Arial Black", Font.ITALIC, 18));
 94             graphics.setFont(new Font("Times New Roman", Font.BOLD, 24));
 95             // 设置字符,字符间距,上边距
 96             graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26);
 97         }
 98 
 99         // 将认证码存入SESSION
100         request.getSession().setAttribute(SESSION_KEY_OF_RAND_CODE, resultCode);
101         // 图象生效
102         graphics.dispose();
103 
104         // 输出图象到页面
105         ImageIO.write(image, "JPEG", response.getOutputStream());
106     }
107 
108     @Override
109     public void doPost(final HttpServletRequest request,
110             final HttpServletResponse response) throws ServletException,
111             IOException {
112         doGet(request, response);
113     }
114 
115     /**
116      * @return 随机码
117      */
118     private String exctractRandCode() {
119         final String randCodeType = "5";
120         int randCodeLength = Integer.parseInt("4");
121         if (randCodeType == null) {
122             return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength);
123         } else {
124             switch (randCodeType.charAt(0)) {
125             case '1':
126                 return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength);
127             case '2':
128                 return RandCodeImageEnum.LOWER_CHAR.generateStr(randCodeLength);
129             case '3':
130                 return RandCodeImageEnum.UPPER_CHAR.generateStr(randCodeLength);
131             case '4':
132                 return RandCodeImageEnum.LETTER_CHAR.generateStr(randCodeLength);
133             case '5':
134                 return RandCodeImageEnum.ALL_CHAR.generateStr(randCodeLength);
135 
136             default:
137                 return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength);
138             }
139         }
140     }
141 
142     /**
143      * 描述:
144      * 
145      * @param fc
146      *            描述:
147      * @param bc
148      *            描述:
149      * 
150      * @return 描述:
151      */
152     private Color getRandColor(int fc, int bc) { // 取得给定范围随机颜色
153         final Random random = new Random();
154         if (fc > 255) {
155             fc = 255;
156         }
157         if (bc > 255) {
158             bc = 255;
159         }
160 
161         final int r = fc + random.nextInt(bc - fc);
162         final int g = fc + random.nextInt(bc - fc);
163         final int b = fc + random.nextInt(bc - fc);
164 
165         return new Color(r, g, b);
166     }
167 }
168 
169 /**
170  * 验证码辅助类
171  * 
172  */
173 enum RandCodeImageEnum {
174     /**
175      * 混合字符串
176      */
177     ALL_CHAR("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
178     /**
179      * 字符
180      */
181     LETTER_CHAR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
182     /**
183      * 小写字母
184      */
185     LOWER_CHAR("abcdefghijklmnopqrstuvwxyz"),
186     /**
187      * 数字
188      */
189     NUMBER_CHAR("0123456789"),
190     /**
191      * 大写字符
192      */
193     UPPER_CHAR("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
194     /**
195      * 待生成的字符串
196      */
197     private String charStr;
198 
199     /**
200      * @param charStr
201      */
202     private RandCodeImageEnum(final String charStr) {
203         this.charStr = charStr;
204     }
205 
206     /**
207      * 生产随机验证码
208      * 
209      * @param codeLength
210      *            验证码的长度
211      * @return 验证码
212      */
213     public String generateStr(final int codeLength) {
214         final StringBuffer sb = new StringBuffer();
215         final Random random = new Random();
216         final String sourseStr = getCharStr();
217 
218         for (int i = 0; i < codeLength; i++) {
219             sb.append(sourseStr.charAt(random.nextInt(sourseStr.length())));
220         }
221 
222         return sb.toString();
223     }
224 
225     /**
226      * @return the {@link #charStr}
227      */
228     public String getCharStr() {
229         return charStr;
230     }
231 
232 }
原文地址:https://www.cnblogs.com/rain-in-summer/p/7680273.html