原理:页面端通过定义img的src直接请求到服务器端,服务器端生成验证码图片,保存验证码值,并将图片通过流的方式返回到页面端。
生成验证码图片:通过Java绘制2D图片。下面代码:
- /**
- * 随机生成验证码
- */
- public ModelAndView createCheckCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
- //加个线程休眠2秒是为了查看页面loading效果
- // Thread t = new Thread();
- // try {
- // t.sleep(2000);
- // } catch (InterruptedException e) {
- // e.printStackTrace();
- // }
- //获取一个参数,是为区别html的img元素每次提交过来的src不同,达到更换验证码图片效果
- String nowCode = request.getParameter("nowCode");
- if(nowCode == null){
- return null;
- }
- //验证码图片的宽度。
- int width = 60;
- //验证码图片的高度。
- int height = 20;
- //验证码字符个数
- int codeCount = 4;
- //随机字符左右距离
- int marginLeft = 12;
- //字体高度
- int fontHeight = 15;
- //验证码字符与图片上边距的距离
- int marginTop = 15;
- //基础字符
- char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
- //初始化图像的Buffer对象
- BufferedImage bufferedImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
- //创建图像画布
- Graphics2D g = bufferedImage.createGraphics();
- //初始化一个随机数生成器类
- Random random = new Random();
- //将图像填充为白色
- g.setColor(Color.WHITE);
- //图像上实心白色矩形框
- g.fillRect(0, 0, width, height);
- //在图像上画一个空心的黑色边框
- g.setColor(Color.BLACK);
- g.drawRect(0, 0, width - 1, height - 1);
- //随机产生10条干扰线,使图象中的验证码不易被自动识别程序解析出来,干扰线多了字符看不清
- //g.setColor(Color.GRAY);
- g.setColor(new Color(127, 131, 142)); //灰色的干扰线容易看点
- for(int i = 0; i < 10; i++){
- int gx = random.nextInt(width); //在整个图像区域内产生干扰线
- int gy = random.nextInt(height);
- int gxl = random.nextInt(width);
- int gyl = random.nextInt(height);
- g.drawLine(gx, gy, gx + gxl, gy + gyl); //画线,两头的XY坐标
- }
- //randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
- StringBuffer randomCode = new StringBuffer();
- int red = 0;
- int green = 0;
- int blue = 0;
- //创建字体,字体的大小应该根据图片的高度来定。
- Font fontCode = new Font("Microsoft YaHei", Font.BOLD, fontHeight);
- //设置字体。
- g.setFont(fontCode);
- //随机产生基础字符内的验证码。
- for (int i = 0; i < codeCount; i++) {
- //在上面定义的基础字符内随机产生验证码
- String strRand = String.valueOf(codeSequence[random.nextInt(36)]);
- //RGB随机产生值,这样输出的每位数字的颜色值都不同
- red = random.nextInt(255);
- green = random.nextInt(255);
- blue = random.nextInt(255);
- //将随机产生的颜色值配置在验证码中
- g.setColor(new Color(red, green, blue));
- //旋转文本
- //g.rotate(random.nextInt(2) * Math.PI / 180);
- //平移原点到图形环境的中心 ,这个方法的作用实际上就是将字符串移动到某一个位置
- //g.translate(1, 1);
- g.drawString(strRand, (i + 1) * marginLeft - 5, marginTop);
- //组合产生的验证码
- randomCode.append(strRand);
- }
- //System.out.println(randomCode.toString());
- //将产生的随机数存在session中,用作比对页面上输入的验证码值
- request.getSession().setAttribute("checkCodeValue", randomCode.toString());
- //禁止图像缓存。
- response.setHeader("Pragma", "no-cache");
- response.setHeader("Cache-Control", "no-cache");
- response.setDateHeader("Expires", 0);
- //设置图像返回客户端类型
- response.setContentType("image/jpeg");
- //将图像以流的方式输出
- ServletOutputStream sos = response.getOutputStream();
- ImageIO.write(bufferedImage, "jpeg", sos);
- sos.close();
- return null;
- }
- /**
- * 验证码校验
- */
- public ModelAndView checkCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String nowCheckCodeValue = request.getParameter("checkCodeValue");
- String checkCodeValue = (String) request.getSession().getAttribute("checkCodeValue");
- //输入的验证码值和session中的进行比对,都转换成大写,因为基础字符中就是全大写,这样页面端可以忽略大小写
- if(nowCheckCodeValue.toUpperCase().equals(checkCodeValue)){
- response.setContentType("text/html;charset=UTF-8");
- response.getWriter().write("成功");
- return null;
- }else{
- response.setContentType("text/html;charset=UTF-8");
- response.getWriter().write("失败");
- return null;
- }
- }
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%String path = request.getContextPath();%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>验证码测试</title>
- <script type="text/javascript" src="<%=path%>/resources/easyui/jquery.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function(){
- $('#img-checkcode').bind('click', function () { /**为验证码图片绑定更换验证码事件**/
- $("#img-checkcode").attr("src",'loading.gif');
- var url = '/swmis/manage/init.do?method=createCheckCode';
- url += "&nowCode=" + (new Date()).getTime();
- this.src = url;
- });
- setTimeout(function(){ /**初始化生成验证码,写个setTimeout是为了查看loading图片效果**/
- $("#img-checkcode").attr("src",'/swmis/manage/init.do?method=createCheckCode&nowCode=' + (new Date()).getTime());
- },2000);
- });
- function subOk(){ /**提交验证码比对**/
- var checkCodeValue = $("#txtCheckCode").val();
- $.ajax({
- type:'POST',
- async:true,
- url: '/swmis/manage/init.do?method=checkCode',
- data: {
- checkCodeValue : checkCodeValue
- },
- success:function(data){
- alert(data);
- }
- });
- }
- </script>
- </head>
- <body>
- <table style="margin: 26px auto;" cellpadding="2" cellspacing="2" width="600px" height="80px">
- <tr>
- <td width="100px" align="right">
- <label>用户名:</label>
- </td>
- <td width="200px">
- <input type="text" class="txt" id="txtUserName" name="txtUserName" value="admin" />
- </td>
- <td rowspan="2" align="left" width="200px">
- <a href=javascript:login() class="btnLogin"></a>
- </td>
- </tr>
- <tr>
- <td width="100px" align="right">
- <label>密码:</label>
- </td>
- <td width="200px">
- <input type="password" class="txt" id="txtPassword" name="txtPassword" value="admin" />
- </td>
- </tr>
- <tr>
- <td width="100px" align="right">
- <label>验证码:</label>
- </td>
- <td width="200px">
- <input type="text" style="vertical-align: middle;" id="txtCheckCode" name="txtCheckCode" value="" />
- <img style="vertical-align: middle;" id="img-checkcode" alt="猛击更换!" title="猛击更换!" src="loading.gif" style=" cursor:pointer" />
- <!-- <img style="vertical-align: middle;" id="img-checkcode" alt="猛击更换!" title="猛击更换!" src="/swmis/manage/init.do?method=createCheckCode&nowCode=1" style=" cursor:pointer" /> -->
- </td>
- </tr>
- <tr>
- <td width="200px" colspan="2">
- <input type="button" class="txt" id="btnSub" name="btnSub" value="提交" onclick="subOk()" />
- </td>
- </tr>
- </table>
- </body>
- </html>