当前位置: 移动技术网 > IT编程>开发语言>Java > Spring框架生成图片验证码实例

Spring框架生成图片验证码实例

2019年07月22日  | 移动技术网IT编程  | 我要评论
这篇文章会从前台页面到后台实现完整的讲解,下面跟着小编一起来看看。 1、前台的代码,image.jsp <%@ page language="java"

这篇文章会从前台页面到后台实现完整的讲解,下面跟着小编一起来看看。

1、前台的代码,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="${pagecontext.request.contextpath }/static/js/jquery-1.10.2.min.js"></script>
</head>
<body>

 <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>

<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){
 var url = "${pagecontext.request.contextpath}/checkimagecode";
 $.get(url,{"validatecode":code},function(data){
 if(data=="ok"){
 alert("ok!")
 }else{
 alert("error!")
 flushvalidatecode();
 }
 })
}

</script>

</body>
</html>

2、后台代码imagegencontroller.java

package com.dufyun.springmvc.web.controller;

import javax.servlet.http.cookie;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;

import org.springframework.stereotype.controller;
import org.springframework.util.stringutils;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.responsebody;

import com.dufy.javaweb.test.randomvalidatecode;

@controller
public class imagegencontroller {


 @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");
  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"; 

  }
  return "error";
  //这里我没有进行字母大小模糊的验证处理,感兴趣的你可以去试一下!
 }

}

3、生成验证码的工具类randomvalidatecode.java

package com.dufy.javaweb.test;


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();
   }
  }
 }

}

4、总结

本文的内容到这就结束了,如果对里面的地方有不懂的地方,可以留言讨论。希望本文的内容对大家的学习工作能有所帮助。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网