1 ```
2 Java验证码案例(基于springMVC方式)
3
4 验证码工具类
5 package com.ekyb.common.util;
6
7 import java.awt.Color;
8 import java.awt.Font;
9 import java.awt.Graphics;
10
11 import java.awt.image.BufferedImage;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.List;
15 import java.util.Random;
16
17 import javax.servlet.http.HttpServletRequest;
18
19 import org.springframework.beans.factory.annotation.Value;
20 import org.springframework.stereotype.Component;
21
22 /**
23 * 图片验证码生成类
24 *
25 * @author gx
26 */
27 @Component("imageCode")
28 public class ImageCode {
29 /*
30 * Spring 3支持@value注解的方式获取properties文件中的配置值,大简化了读取配置文件的代码。
31 * 在applicationContext.xml文件中配置properties文件,在bean中使用@value注解获取配置文件的值
32 * 即使给变量赋了初值也会以配置文件的值为准。
33 */
34 @Value("${ImageCode.width}")
35 private int width;
36
37 @Value("${ImageCode.height}")
38 private int height;
39
40 @Value("${ImageCode.codeLength}")
41 private int codeLength;
42
43 @Value("${ImageCode.randomString}")
44 private String randomString;
45
46 @Value("${ImageCode.sessionKey}")
47 private String sessionKey;
48
49 @Value("${ImageCode.font.name}")
50 private String fontName;
51
52 @Value("${ImageCode.font.style}")
53 private int fontStyle;
54
55 @Value("${ImageCode.font.size}")
56 private int fontSize;
57
58 public BufferedImage getImage(HttpServletRequest request) {
59 // 在内存中创建图片
60 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
61 // 获取图片上下文
62 Graphics g = image.getGraphics();
63 // 生成随机类
64 Random random = new Random();
65 // 设定背景颜色
66 g.setColor(getRandColor(100, 250));
67 g.fillRect(0, 0, width, height);
68 // 设定字体
69 g.setFont(new Font(fontName, fontStyle, fontSize));
70 g.setColor(getRandColor(160, 200));
71 for (int i = 0; i < 155; i++) {
72 int x = random.nextInt(width);
73 int y = random.nextInt(height);
74 int xl = random.nextInt(12);
75 int yl = random.nextInt(12);
76 g.drawLine(x, y, xl, y + yl);
77 }
78 // 取随机产生的认证码
79 String sRand = randomRand(codeLength);
80 int strWidth = width / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength - fontSize;
81 int strHeight = height / 2 + g.getFontMetrics().getHeight() / 4;
82 for (int i = 0; i < codeLength; i++) {
83 String rand = sRand.substring(i, i + 1);
84 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
85 g.drawString(rand, 13 * i + 6 + strWidth, strHeight);
86 }
87 //System.out.println(sRand);
88 request.getSession().setAttribute(sessionKey, sRand);
89 request.setAttribute("sRand", sRand);
90 g.dispose();
91 return image;
92 }
93
94 public static String randomResult(int length) {
95 String[] i = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
96 List<String> l = new ArrayList<String>();
97 l.addAll(Arrays.asList(i));
98 Random ran = new Random();
99 String s = "";
100 while (l.size() > 10 - length)
101 s += l.remove(ran.nextInt(l.size()));
102 s = s.replaceAll("^(0)(\\d)", "$2$1");
103 return s;
104 }
105
106 // 给定范围获取随机颜色
107 public Color getRandColor(int fc, int bc) {
108 Random random = new Random();
109 if(fc > 255) {
110 fc = 255;
111 }
112 if(bc > 255) {
113 bc = 255;
114 }
115 int r = fc + random.nextInt(bc - fc);
116 int g = fc + random.nextInt(bc - fc);
117 int b = fc + random.nextInt(bc - fc);
118 return new Color(r, g, b);
119
120 }
121
122 private String randomRand(int n) {
123 String rand = "";
124 int len = randomString.length() - 1;
125 double r;
126 for (int i = 0; i < n; i++) {
127 r = ((Math.random())) * len;
128 rand = rand + randomString.charAt((int) r);
129 }
130 return rand;
131 }
132
133 public int getWidth() {
134 return width;
135 }
136
137 public void setWidth(int width) {
138 this.width = width;
139 }
140
141 public int getHeight() {
142 return height;
143 }
144
145 public void setHeight(int height) {
146 this.height = height;
147 }
148
149 public int getCodeLength() {
150 return codeLength;
151 }
152
153 public void setCodeLength(int codeLength) {
154 this.codeLength = codeLength;
155 }
156
157 public String getRandomString() {
158 return randomString;
159 }
160
161 public void setRandomString(String randomString) {
162 this.randomString = randomString;
163 }
164
165 public String getSessionKey() {
166 return sessionKey;
167 }
168
169 public void setSessionKey(String sessionKey) {
170 this.sessionKey = sessionKey;
171 }
172
173 public String getFontName() {
174 return fontName;
175 }
176
177 public void setFontName(String fontName) {
178 this.fontName = fontName;
179 }
180
181 public int getFontStyle() {
182 return fontStyle;
183 }
184
185 public void setFontStyle(int fontStyle) {
186 this.fontStyle = fontStyle;
187 }
188
189 public int getFontSize() {
190 return fontSize;
191 }
192
193 public void setFontSize(int fontSize) {
194 this.fontSize = fontSize;
195 }
196
197 }
198
199 -----------------------------------------------
200 读取config.properties配置的验证码和图片设置
201
202 #ImageCode生成器配置
203 ImageCode.width=120
204 ImageCode.height=38
205 ImageCode.codeLength=4
206 ImageCode.randomString=ABCDEFGHIJKLMNPQRSTUVWXYZ1234567890abcdefghijkmnpqrstuvwxyz
207 ImageCode.sessionKey=SESSIONCODE
208 ImageCode.font.name=Times New Roman
209 ImageCode.font.style=0
210 ImageCode.font.size=18
211 -------------------------------------------------
212 springMVC action中的代码
213 package com.ekyb.common.auContract.action;
214
215 import java.io.IOException;
216
217 import javax.annotation.Resource;
218 import javax.imageio.ImageIO;
219 import javax.servlet.ServletOutputStream;
220 import javax.servlet.http.HttpServletRequest;
221 import javax.servlet.http.HttpServletResponse;
222
223 import org.springframework.stereotype.Controller;
224 import org.springframework.web.bind.annotation.RequestMapping;
225
226 import com.ekyb.common.util.ImageCode;
227
228 @Controller
229 @RequestMapping(value="/yanZhen")
230 public class YanZhenMaAction {
231 /*
232 * @Resource默认按 byName 自动注入,是J2EE提供的, 需导入Package: javax.annotation.Resource;
233 *
234 * @Resource有两个中重要的属性:name和type ,而Spring将@Resource注解的name属性解析为bean的
235 * 名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用 type属性时则使用
236 * byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用by Name自动注入策略。
237 */
238 @Resource
239 ImageCode imageCode;
240
241 private static String sRand;
242
243 @RequestMapping(value = "/openLoginPage")
244 public String openLoginPage(HttpServletRequest request, HttpServletResponse response) {
245 String msg=request.getParameter("msg");
246 if(msg==null&& msg.isEmpty()){
247 //得到用户读入框信息,如果没有输入或者为空,直接跳转到验证失败页面
248 return "error";
249 }else{
250 if(sRand.equalsIgnoreCase((msg))){
251 //得到用户输入的验证码匹配成功,跳转到验证通过页面
252 return "ok";
253 }else{
254 //得到用户输入的验证码匹配失败,跳转到验证失败页面
255 return "error";
256 }
257 }
258 }
259
260 @RequestMapping(value = "/getImage")
261 public void getImage(HttpServletRequest request, HttpServletResponse response
262 ) throws IOException {
263 // 禁止图片缓存
264 response.setHeader("Pragma", "no-cache");
265 response.setHeader("Cache-Control", "no-cache");
266 response.setDateHeader("Expires", 0);
267 response.setContentType("image/jpeg");
268 // 将图像输出到servlet输出流中
269 ServletOutputStream sos = response.getOutputStream();
270 ImageIO.write(imageCode.getImage(request), "jpeg", sos);
271 sos.close();
272 sRand=(String)request.getAttribute("sRand");
273 String result="ok";
274
275 }
276 }
277 -------------------------------------------------
278 前端登录页面代码
279 <%@ page language="java" pageEncoding="utf-8"%>
280 <%
281 String path = request.getContextPath();
282 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
283 %>
284 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
285 <html>
286 <head>
287 <base href="<%=basePath%>">
288 <title>登录</title>
289 </head>
290 <script type="text/javascript" src="js/jquery-easyui/jquery.min.js"></script>
291 <body>
292 <!-- cursor: pointer;鼠标放上显示手; title:鼠标放上时显示的文字 -->
293 <img id="imageCode" alt="" src="" οnclick="checkcode()" style="cursor: pointer;" title="点我更换验证码" />
294 <br>
295 <form action="<%=basePath%>yanZhen/openLoginPage" method="post">
296 <input type="text" value="" name="msg">
297 <input type="submit" value="提交">
298 </form>
299 </body>
300 <script type="text/javascript">
301 var basePath = "<%=basePath%>";
302 $(function() {
303 checkcode();
304 });
305 function checkcode() {
306 var XMLHttp = null;
307 if (window.XMLHttpRequest) {
308 XMLHttp = new XMLHttpRequest();
309 } else if (window.ActiveXObject) {
310 XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
311 }
312 XMLHttp.onreadystatechange = function() {
313 if (XMLHttp.readyState == 4) {
314 //改变验证码图片
315 $("#imageCode").attr("src",(basePath + "/yanZhen/getImage?" + new Date()));
316 }
317 };
318 //将请求发送出去
319 //加上 new Date()防止浏览器缓存,不重新发送请求
320 XMLHttp.open("GET", basePath + "/yanZhen/getImage?" + new Date(), true);
321 XMLHttp.send(null);
322 }
323 </script>
324 </html>
325 -----------------------------------------------------
326 登录成页面ok.jsp
327 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
328 <%
329 String path = request.getContextPath();
330 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
331 + path + "/";
332 %>
333
334 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
335 <html>
336 <head>
337 <base href="<%=basePath%>">
338
339 <title>验证通过</title>
340 </head>
341 <body>
342 <h2>验证通过</h2>
343 </body>
344 </html>
345 -------------------------------------------------
346 登录失败页面error.jsp
347 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
348 <%
349 String path = request.getContextPath();
350 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
351 + path + "/";
352 %>
353 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
354 <html>
355 <head>
356 <base href="<%=basePath%>">
357
358 <title>验证失败</title>
359 </head>
360
361 <body>
362 <h2>验证失败</h2>
363 </body>
364 </html>
365 --------------------
366 ==****注意个别路径根据自己的文件路劲更改==
如果有误请多指教
367 ```