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" src="" onclick="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 ```
时间: 2024-10-08 10:44:26