1.jsp 登录界面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>员工登录</title> </head> <body style="background-image: url(${pageContext.request.contextPath}/image/timg.jpg);-moz-background-size: 80% 80%; background-size: 100%; background-repeat:no-repeat;"> <div align="center" style="padding-top: 50px;"> <form action="${pageContext.request.contextPath}/main/login.do" method="post" onsubmit="return checkForm()"> <table width="700" height="400" style="background-color: rgba(500, 500, 500, 0.5);"> <tr height="150"> </tr> <tr height="30" style="margin-top: 200px;"> <td width="40%"></td> <td width="10%">工号:</td> <td><input type="text" value="${userName}" name="username" id="userName" /></td> <td width="40%"></td> </tr> <tr height="30"> <td width="40%"></td> <td width="10%">密 码:</td> <td><input type="password" value="${password}" name="password" id="password" /></td> <td width="30%"></td> </tr> <tr> <td weight="40%"></td> <td width="15%">验证码:</td> <td><input type="text" value="${checkCode}" name="checkCode1" id="checkCode1"></td> <td><img id="checkimg" name="image" src="${pageContext.request.contextPath}/pictureCheckCode" > <input type="button" value="看不清? 换一张。" onclick="checkCode()" /></td> </tr> <tr height="30"> <td width="40%"></td> <td width="10%"><input type="submit" value="登录" /></td> <td width="10%"><input type="reset" value="重置" /></td> <td width="10%"><input type="button" value="注册" onclick="regist()" /></td> <td width="30%"></td> </tr> <tr height="10"> <td width="40%"></td> <td colspan="3"><font color="red" id="login_err">${error}</font></td> </tr> <tr> <td></td> </tr> </table> </form> </div> <script type="text/javascript"> function checkForm() { var userName = document.getElementById("userName").value; var password = document.getElementById("password").value; var checkCode = document.getElementById("checkCode").value; if (userName == null || userName == "") { document.getElementById("login_err").innerHTML = "用户名不能为空"; return false; } if (password == null || password == "") { document.getElementById("login_err").innerHTML = "密码不能为空"; return false; } if (checkCode == null || checkCode == "") { document.getElementById("login_err").innerHTML = "验证码不能为空"; return false; } return true; } function regist() { window.location.href = "${pageContext.request.contextPath}/regist.jsp"; } /* 重新加载验证码,很重要!!! */ function checkCode() { document.getElementById("checkimg").src = "${pageContext.request.contextPath}/pictureCheckCode?time=" + new Date().getTime(); } </script> </body> </html>
2.随机生成验证码图片
@WebServlet("/pictureCheckCode") public class PictureCheckCode extends HttpServlet { private static final long serialVersionUID = 1L; /* 该方法主要作用是获得随机生成的颜色 */ public Color getRandColor(int s, int e) { Random random = new Random(); if (s > 255) s = 255; if (e > 255) e = 255; int r, g, b; r = s + random.nextInt(e - s); // 随机生成RGB颜色中的r值 g = s + random.nextInt(e - s); // 随机生成RGB颜色中的g值 b = s + random.nextInt(e - s); // 随机生成RGB颜色中的b值 return new Color(r, g, b); } private Random r = new Random(); // 随机字符集合中不包括0和o,O,1和l,因为这些不易区分 private String codes = "23456789abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYXZ"; private char randomChar() { int index = r.nextInt(codes.length()); return codes.charAt(index); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); // 设置不缓存图片 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setDateHeader("Expires", 0); // 指定生成的响应图片,一定不能缺少这句话,否则错误. response.setContentType("image/jpeg"); int width = 80, height = 35; // 指定生成验证码的宽度和高度 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 创建BufferedImage对象,其作用相当于一图片 Graphics g = image.getGraphics(); // 创建Graphics对象,其作用相当于画笔 Graphics2D g2d = (Graphics2D) g; // 创建Grapchics2D对象 Random random = new Random(); Font mfont = new Font("楷体", Font.BOLD, 16); // 定义字体样式 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width, height); // 绘制背景 g.setFont(mfont); // 设置字体 g.setColor(getRandColor(180, 200)); // 绘制100条颜色和位置全部为随机产生的线条,该线条为2f for (int i = 0; i < 100; i++) { int x = random.nextInt(width - 1); int y = random.nextInt(height - 1); int x1 = random.nextInt(6) + 1; int y1 = random.nextInt(12) + 1; BasicStroke bs = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); // 定制线条样式 Line2D line = new Line2D.Double(x, y, x + x1, y + y1); g2d.setStroke(bs); g2d.draw(line); // 绘制直线 } //用来保存验证码字符串文本内容 StringBuilder sb = new StringBuilder(); for (int i = 0; i < 4; ++i) {// 随机生成4个字符 String sTemp = String.valueOf(randomChar()); sb.append(sTemp); Color color = new Color(20 + random.nextInt(110), 20 + random.nextInt(110), random.nextInt(110)); g.setColor(color); // 将生成的随机数进行随机缩放并旋转制定角度 PS.建议不要对文字进行缩放与旋转,因为这样图片可能不正常显示 /* 将文字旋转制定角度 */ Graphics2D g2d_word = (Graphics2D) g; AffineTransform trans = new AffineTransform(); trans.rotate((45) * 3.14 / 180, 15 * i + 8, 7); /* 缩放文字 */ float scaleSize = random.nextFloat() + 0.8f; if (scaleSize > 1f) scaleSize = 1f; trans.scale(scaleSize, scaleSize); g2d_word.setTransform(trans); g.drawString(sTemp, 15 * i + 18, 14); } HttpSession session = request.getSession(true); session.setAttribute("randCheckCode", sb.toString()); //System.out.println("sRand="+sb.toString()); g.dispose(); // 释放g所占用的系统资源 ImageIO.write(image, "JPEG", response.getOutputStream()); // 输出图片 } }
3.controller
@RequestMapping(value="login") public String login(String username,String password,HttpSession session,HttpServletRequest request) { //拿到页面传过来的手动输入的验证码, 该验证码要和生成图片上的 //文本验证码比较, 如果相同, 验证码输入成功! String imageText = request.getParameter("checkCode1"); System.out.println("-------------------"+imageText); // 图片的验证码,randCheckCode为PictureCheckCode里的session值
String text = (String) request.getSession().getAttribute("randCheckCode");
System.out.println("-------------------"+text); if(!(text.equals(imageText))) { request.setAttribute("error", "验证码输入错误!"); return "login"; } }