图片验证码的生成

首先先写一个image.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>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.0.0/jquery.min.js"></script>
</head>

 <form action="##" method='post'>
   <input type="hidden" id="userId" name="userId" value=""> 
    <div class="form-group">
     <div class="email controls">
      <input type="text" name='loginName' id="loginName" placeholder="用户名" value="" class='form-control'/>
     </div>
    </div>
    <div class="form-group">
     <div class="pw controls">
      <input type="password" autocomplete="off" id="pwd" name="pwd" placeholder="密码" class='form-control'/>
     </div>
    </div>

    <div class="form-group">
     <div class="email controls">
      <input id="validateCode" onblur="checkImg(this.value)" name="validateCode" type="text" class="form-control" placeholder="输入验证码"/> 
     </div>
     <span class="y_yzimg"><img id="codeValidateImg" onClick="javascript:flushValidateCode();"/></span>
     <p class="y_change"><a href="javascript:flushValidateCode();" >换一张</a></p>
    </div>

    <div class="form-group">
     <span class="text-danger"></span>
    </div>

    <div class="submit">
     <div class="remember">

        <input type="checkbox" name="remember" value="1" class='icheck-me' data-skin="square" data-color="blue" id="remember">

      <label for="remember">记住我</label>
     </div>
     <input type="button" value="登录" onclick="javascript:submitForm();" class='btn btn-primary'>
    </div>
   </form>
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="http://apps.bdimg.com/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
 flushValidateCode();//进入页面就刷新生成验证码
 });

/* 刷新生成验证码 */
function flushValidateCode(){
var validateImgObject = document.getElementById("codeValidateImg");
validateImgObject.src = "${pageContext.request.contextPath }/getSysManageLoginCode?time=" + new Date();
}
/*校验验证码输入是否正确*/
function checkImg(code){
    alert("code:"+code);
 var url = "${pageContext.request.contextPath}/checkimagecode";
 $.get(url,{"validateCode":code},function(data){
 if(data=="ok"){
 alert("ok!")
 }else{
 alert("error!")
 flushValidateCode();
 }
 })
}

</script>

</body>
</html>

然后写一个工具类

package org.seckill.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RandomValidateCode {
     private Random random = new Random();
     private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";// 随机产生的字符串

     private int width = 80;// 图片宽
     private int height = 26;// 图片高
     private int lineSize = 40;// 干扰线数量
     private int stringNum = 4;// 随机产生字符数量

     /*
     * 获得字体
     */
     private Font getFont() {
      return new Font("Fixedsys", Font.CENTER_BASELINE, 18);
     }

     /*
     * 获得颜色
     */
     private Color getRandColor(int fc, int bc) {
      if (fc > 255)
       fc = 255;
      if (bc > 255)
       bc = 255;
      int r = fc + random.nextInt(bc - fc - 16);
      int g = fc + random.nextInt(bc - fc - 14);
      int b = fc + random.nextInt(bc - fc - 18);
      return new Color(r, g, b);
     }

     /*
     * 绘制字符串
     */
     private String drowString(Graphics g, String randomString, int i) {
      g.setFont(getFont());
      g.setColor(new Color(random.nextInt(101), random.nextInt(111), random
        .nextInt(121)));
      String rand = String.valueOf(getRandomString(random.nextInt(randString
        .length())));
      randomString += rand;
      g.translate(random.nextInt(3), random.nextInt(3));
      g.drawString(rand, 13 * i, 16);
      return randomString;
     }

     /*
     * 绘制干扰线
     */
     private void drowLine(Graphics g) {
      int x = random.nextInt(width);
      int y = random.nextInt(height);
      int xl = random.nextInt(13);
      int yl = random.nextInt(15);
      g.drawLine(x, y, x + xl, y + yl);
     }

     /*
     * 获取随机的字符
     */
     public String getRandomString(int num) {
      return String.valueOf(randString.charAt(num));
     }


     /**
     * 生成随机图片
     */
     public void getRandcode(HttpServletRequest request,HttpServletResponse response,String key) {

      // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
      BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_BGR);
      Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
      g.fillRect(0, 0, width, height);
      g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
      g.setColor(getRandColor(110, 133));
      // 绘制干扰线
      for (int i = 0; i <= lineSize; i++) {
       drowLine(g);
      }
      // 绘制随机字符
      String randomString = "";
      for (int i = 1; i <= stringNum; i++) {
       randomString = drowString(g, randomString, i);
      }
      //1:将随机生成的验证码放入Cookie中
      Cookie cookie = new Cookie(key,randomString);
      response.addCookie(cookie);
      //2:将随机生成的验证码放入session中
      String sessionid = request.getSession().getId();
      request.getSession().setAttribute(sessionid+key, randomString);
      System.out.println("*************" + randomString);

      //总结:这两种方式都是很好,
      //(1):使用cookie的方式,将验证码发送到前台浏览器,不安全!不建议使用。
      //(2):使用session的方式,虽然能解决验证码不发送到浏览器,安全性较高了,但是如果用户量太大,这样的存储方式会对服务器造成压力,影响服务器的性能。不建议使用。
      //这里暂时实现用这种方式,好的办法是,在项目中使用的缓存,将生成的验证码存放到缓存中,设置失效时间,这样既可以实现安全性也能减轻服务器的压力。
      g.dispose();
      try {
       ByteArrayOutputStream tmp = new ByteArrayOutputStream();
       ImageIO.write(image, "png", tmp);
       tmp.close();
       Integer contentLength = tmp.size();
       response.setHeader("content-length", contentLength + "");
       response.getOutputStream().write(tmp.toByteArray());// 将内存中的图片通过流动形式输出到客户端
      } catch (Exception e) {
       e.printStackTrace();
      }finally{
       try {
        response.getOutputStream().flush();
        response.getOutputStream().close();
       } catch (Exception e2) {
        e2.printStackTrace();
       }
      }
     }

    }

最后在control控制类里整合

 @RequestMapping(value="/toImg")
    public String toImg(){

     return "image/image";
    }

  //登录获取验证码
    @RequestMapping("/getSysManageLoginCode")
    @ResponseBody
    public String getSysManageLoginCode(HttpServletResponse response,
      HttpServletRequest request) {
     response.setContentType("image/jpeg");// 设置相应类型,告诉浏览器输出的内容为图片
     response.setHeader("Pragma", "No-cache");// 设置响应头信息,告诉浏览器不要缓存此内容
     response.setHeader("Cache-Control", "no-cache");
     response.setHeader("Set-Cookie", "name=value; HttpOnly");//设置HttpOnly属性,防止Xss攻击
     response.setDateHeader("Expire", 0);
     RandomValidateCode randomValidateCode = new RandomValidateCode();
     try {
      randomValidateCode.getRandcode(request, response,"imagecode");// 输出图片方法
     } catch (Exception e) {
      e.printStackTrace();
     }
     return "";
    }

    //验证码验证
    @RequestMapping(value ="/checkimagecode")
    @ResponseBody
    public String checkTcode(HttpServletRequest request,HttpServletResponse response) {
     String validateCode = request.getParameter("validateCode");
     System.out.println("validateCode:---");
     String code = null;
     //1:获取cookie里面的验证码信息
     Cookie[] cookies = request.getCookies();
     for (Cookie cookie : cookies) {
      if ("imagecode".equals(cookie.getName())) {
       code = cookie.getValue();
       break;
      }
     }
     //1:获取session验证码的信息
    // String code1 = (String) request.getSession().getAttribute("");
     //2:判断验证码是否正确
     if(!StringUtils.isEmpty(validateCode) && validateCode.equals(code)){
      return "ok"; 

     }
     re``
urn "error";
     //这里是区分大小写的,没有做模糊处理
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值