欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java实现简单的验证码功能

程序员文章站 2022-03-26 08:05:04
最近要做一个网站,要求实现验证码程序,经过不断调试,终于成功实现功能。一、验证码生成类生成验证码的话需要用到java的graphics类库,画出一个验证码 废话不多说,直接上代码package ver...

最近要做一个网站,要求实现验证码程序,经过不断调试,终于成功实现功能。

一、验证码生成类

生成验证码的话需要用到java的graphics类库,画出一个验证码
废话不多说,直接上代码

package verificationcode;


import java.awt.color;
import java.awt.font;
import java.awt.graphics;
import java.awt.image.bufferedimage;
import java.awt.image.renderedimage;
import java.io.file;
import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.outputstream;
import java.util.hashmap;
import java.util.map;
import java.util.random;

import javax.imageio.imageio;

public class generatecode {
 private static int width = 150;// 定义图片的width
 private static int height = 48;// 定义图片的height
 private static int codecount = 4;// 定义图片上显示验证码的个数
 private static int xx = 25;
 private static int fontheight = 42;
 private static int codey = 42;
 private static 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' };

 /**
  * 生成一个map集合
  * code为生成的验证码
  * codepic为生成的验证码bufferedimage对象
  * @return
  */
 public static map<string,object> generatecodeandpic() {
  // 定义图像buffer
  bufferedimage buffimg = new bufferedimage(width, height, bufferedimage.type_int_rgb);
  // graphics2d gd = buffimg.creategraphics();
  // graphics2d gd = (graphics2d) buffimg.getgraphics();
  graphics gd = buffimg.getgraphics();
  // 创建一个随机数生成器类
  random random = new random();
  // 将图像填充为白色
  gd.setcolor(color.white);
  gd.fillrect(0, 0, width, height);

  // 创建字体,字体的大小应该根据图片的高度来定。
  font font = new font("fixedsys", font.bold, fontheight);
  // 设置字体。
  gd.setfont(font);

  // 画边框。
  gd.setcolor(color.black);
  gd.drawrect(0, 0, width - 1, height - 1);
  gd.setfont(font);
  // 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。
  int red = 0, green = 0, blue = 0;


  // randomcode用于保存随机产生的验证码,以便用户登录后进行验证。
  stringbuffer randomcode = new stringbuffer();


  // 随机产生codecount数字的验证码。
  for (int i = 0; i < codecount; i++) {
   // 得到随机产生的验证码数字。
   string code = string.valueof(codesequence[random.nextint(36)]);
   // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
   red = random.nextint(255);
   green = random.nextint(255);
   blue = random.nextint(255);
   // 用随机产生的颜色将验证码绘制到图像中。
   gd.setcolor(new color(red, green, blue));
   gd.drawstring(code, (i + 1) * xx, codey);

   // 将产生的四个随机数组合在一起。
   randomcode.append(code);
  }
  for (int i = 0; i < 60; i++) {
   red = random.nextint(255);
   green = random.nextint(255);
   blue = random.nextint(255);
   // 用随机产生的颜色将验证码绘制到图像中。
   gd.setcolor(new color(red, green, blue));
   int x = random.nextint(width);
   int y = random.nextint(height);
   int xl = random.nextint(50);
   int yl = random.nextint(50);
   gd.drawline(x, y, x + xl, y + yl);
  }
  map<string,object> map =new hashmap<string,object>();
  //存放验证码
  map.put("code", randomcode);
  //存放生成的验证码bufferedimage对象
  map.put("codepic", buffimg);
  return map;
 }

 public static void main(string[] args) throws exception {
  //创建文件输出流对象
  file file = new file("webroot/image/"+system.currenttimemillis()+".jpg");
  fileoutputstream out = null;
  try {
   if (!file.exists()) {
    // 先得到文件的上级目录,并创建上级目录,在创建文件
    file.getparentfile().mkdir();
    file.createnewfile();
   }
   out = new fileoutputstream(file);
  map<string,object> map = generatecode.generatecodeandpic();
  imageio.write((renderedimage) map.get("codepic"), "jpeg", out);
  system.out.println("验证码的值为:"+map.get("code"));
  } catch (filenotfoundexception e) {
   e.printstacktrace();
  } catch (ioexception e) {
   e.printstacktrace();
  }
 }
}

二、验证码验证类

package verificationcode;


import java.io.ioexception;
import javax.servlet.servletexception;
import javax.servlet.annotation.webservlet;
import javax.servlet.http.httpservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import javax.servlet.http.httpsession;


@webservlet("/checkcode")
public class checkcode extends httpservlet {
 private static final long serialversionuid = 1l;

 protected void doget(httpservletrequest request, httpservletresponse response)
   throws servletexception, ioexception {

 }

 protected void dopost(httpservletrequest request, httpservletresponse response)
   throws servletexception, ioexception {
  string code = request.getparameter("code");
  response.setcharacterencoding("utf-8");//保证格式正确
  response.setcontenttype("text/html");
  // 验证验证码
  string sessioncode = request.getsession().getattribute("code").tostring();
  if (code != null && !"".equals(code) && sessioncode != null && !"".equals(sessioncode)) {
   if (code.equalsignorecase(sessioncode)) {
    response.getwriter().println("验证通过!");
   } else {
    response.getwriter().println("验证失败!");
   }
  } else {
   response.getwriter().println("验证失败!");
  }
 }

}

三、验证码传输类

用到doget方法

package verificationcode;

import java.awt.color;
import java.awt.font;
import java.awt.graphics;
import java.awt.image.bufferedimage;
import java.awt.image.renderedimage;
import java.io.ioexception;
import java.util.hashmap;
import java.util.map;
import java.util.random;

import javax.imageio.imageio;
import javax.servlet.servletexception;
import javax.servlet.servletoutputstream;
import javax.servlet.annotation.webservlet;
import javax.servlet.http.httpservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import javax.servlet.http.httpsession;

import verificationcode.generatecode;
/**
 * servlet implementation class codeservlet
 */
@webservlet("/getcode")
public class codeservlet extends httpservlet {
 private static final long serialversionuid = 1l;

 protected void doget(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception {
  // 调用工具类生成的验证码和验证码图片
  map<string, object> codemap = generatecode.generatecodeandpic();

  // 将四位数字的验证码保存到session中。
  httpsession session = req.getsession();
  session.setattribute("code", codemap.get("code").tostring());

  // 禁止图像缓存。
  resp.setheader("pragma", "no-cache");
  resp.setheader("cache-control", "no-cache");
  resp.setdateheader("expires", 0);

  resp.setcontenttype("image/jpeg");

  // 将图像输出到servlet输出流中。
  servletoutputstream sos;
  try {
   sos = resp.getoutputstream();
   imageio.write((renderedimage) codemap.get("codepic"), "jpeg", sos);
   sos.close();
  } catch (ioexception e) {
   // todo auto-generated catch block
   e.printstacktrace();
  }

 }

}

四、jsp验证demo

<%@ page language="java" contenttype="text/html; charset=utf-8"
 pageencoding="utf-8"%>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>验证码页面</title>
<script type="text/javascript"
 src="${pagecontext.request.contextpath}/js/jquery.js"></script>
</head>
<body>
 <form action="${pagecontext.request.contextpath}/checkcode" method="post">
  请输入验证码:<input type="text" name="code" style="width: 80px;" /> <div id=random> <img id="imgobj" alt="验证码"
   src="${pagecontext.request.contextpath}/getcode"> </div><button id="b01" type="button">改变内容</button><br/> <input
   type="submit" value="提交" />
 </form>
</body>
<script type="text/javascript">
 $(function() {
  //response.getwriter().println("验证失败!");
 });

 $("#b01").click( function changeimg() { 


   $("#random").html("<img id='imgobj' alt='验证码' src='${pagecontext.request.contextpath}/getcode'>")  
   var imgsrc = $("#imgobj"); 
  var src = imgsrc.attr("src");  
  imgsrc.attr("src", chgurl(src)); 
 });

 // 时间戳
 // 为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
 function chgurl(url) {
  var timestamp = (new date()).valueof();
  url = url.substring(0, 20);
  if ((url.indexof("&") >= 0)) {
   url = url + "×tamp=" + timestamp;
  } else {
   url = url + "?timestamp=" + timestamp;
  }
  return url;
 }

</script>
</html>

总结

虽然只是一个小小的demo,但是实际上用到了许多知识,比如生成验证码的画图,传输验证码doget,验证验证码的dopost和ajax动态更换验证码,麻雀虽小五脏俱全啊。

参考网址: java实现验证码的产生和验证