java实现简单的验证码功能

 更新时间:2020年04月23日 15:30:34   作者:踢飞足球  
这篇文章主要为大家详细介绍了java实现简单的验证码功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

一、验证码生成类

生成验证码的话需要用到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实现验证码的产生和验证

更多关于java验证码的精彩文章请点击专题: java验证码大全 进行参考

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java实现银行存取款

    Java实现银行存取款

    这篇文章主要为大家详细介绍了Java实现银行存取款,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • java程序运行时内存分配详解

    java程序运行时内存分配详解

    这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下
    2016-07-07
  • java中的instanceof关键字详细解读

    java中的instanceof关键字详细解读

    这篇文章主要介绍了java中的instanceof关键字详细解读,instanceof 是 Java 的保留关键字,它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型,需要的朋友可以参考下
    2024-01-01
  • Spring JPA使用CriteriaBuilder动态构造查询方式

    Spring JPA使用CriteriaBuilder动态构造查询方式

    这篇文章主要介绍了Spring JPA使用CriteriaBuilder动态构造查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java 添加、读取和删除 Excel 批注的操作代码

    Java 添加、读取和删除 Excel 批注的操作代码

    这篇文章主要介绍了Java 添加、读取和删除 Excel 批注的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 详解springboot中各个版本的redis配置问题

    详解springboot中各个版本的redis配置问题

    这篇文章主要介绍了详解springboot中各个版本的redis配置问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Java数据结构之图的两种搜索算法详解

    Java数据结构之图的两种搜索算法详解

    在很多情况下,我们需要遍历图,得到图的一些性质。有关图的搜索,最经典的算法有深度优先搜索和广度优先搜索,接下来我们分别讲解这两种搜索算法,需要的可以参考一下
    2022-11-11
  • 关于在Java中使用预定义类

    关于在Java中使用预定义类

    这篇文章主要介绍了关于在Java中使用预定义类,预定义类就是Java类库(或第三方库)中已经定义好的类,例如,Math 类和 Date 类,需要的朋友可以参考下
    2023-05-05
  • SpringBoot集成Kaptcha验证码的详细过程

    SpringBoot集成Kaptcha验证码的详细过程

    Kaptcha是一个强大而灵活的Java验证码生成库,通过合理的配置和使用,它可以有效地提高web应用的安全性,防止自动化程序的滥用,这篇文章主要介绍了SpringBoot集成Kaptcha验证码,需要的朋友可以参考下
    2024-07-07
  • SpringBoot 整合数据源的具体实践

    SpringBoot 整合数据源的具体实践

    本文主要介绍了SpringBoot 整合数据源的具体实践,利用 Spring Boot 的自动配置和简化的注解来简化数据源配置工作,从而更专注于应用程序的业务逻辑开发,感兴趣的可以了解一下
    2023-11-11

最新评论