广告位联系
返回顶部
分享到

java实现简单的验证码功能的详解

java 来源:互联网搜集 作者:秩名 发布时间:2020-04-23 21:01:31 人浏览
摘要

最近要做一个网站,要求实现验证码程序,经过不断调试,终于成功实现功能。 一、验证码生成类 生成验证码的话需要用到java的Graphics类库,画出一个验证码 废话不多说,直接上代码 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

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

一、验证码生成类

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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();
  }
 }
}
 

二、验证码验证类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<%@ 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动态更换验证码,麻雀虽小五脏俱全啊。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/qq_39263280/article/details/81457299
相关文章
  • SpringBoot自定义错误处理逻辑介绍

    SpringBoot自定义错误处理逻辑介绍
    1. 自定义错误页面 将自定义错误页面放在 templates 的 error 文件夹下,SpringBoot 精确匹配错误信息,使用 4xx.html 或者 5xx.html 页面可以打印错误
  • Java实现手写一个线程池的代码

    Java实现手写一个线程池的代码
    线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个知识点,那么大家知道它的实现原理和
  • Java实现断点续传功能的代码

    Java实现断点续传功能的代码
    题目实现:网络资源的断点续传功能。 二、解题思路 获取要下载的资源网址 显示网络资源的大小 上次读取到的字节位置以及未读取的字节
  • 你可知HashMap为什么是线程不安全的
    HashMap 的线程不安全 HashMap 的线程不安全主要体现在下面两个方面 在 jdk 1.7 中,当并发执行扩容操作时会造成环形链和数据丢失的情况 在
  • ArrayList的动态扩容机制的介绍

    ArrayList的动态扩容机制的介绍
    对于 ArrayList 的动态扩容机制想必大家都听说过,之前的文章中也谈到过,不过由于时间久远,早已忘却。 所以利用这篇文章做做笔记,加
  • JVM基础之字节码的增强技术介绍

    JVM基础之字节码的增强技术介绍
    字节码增强技术 在上文中,着重介绍了字节码的结构,这为我们了解字节码增强技术的实现打下了基础。字节码增强技术就是一类对现有字
  • Java中的字节码增强技术

    Java中的字节码增强技术
    1.字节码增强技术 字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。 参考地址 2.常见技术 技术分类 类
  • Redis BloomFilter布隆过滤器原理与实现

    Redis BloomFilter布隆过滤器原理与实现
    Bloom Filter 概念 布隆过滤器(英语:Bloom Filter)是1970年由一个叫布隆的小伙子提出的。它实际上是一个很长的二进制向量和一系列随机映射
  • Java C++算法题解leetcode801使序列递增的最小交换次

    Java C++算法题解leetcode801使序列递增的最小交换次
    题目要求 思路:状态机DP 实现一:状态机 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int minSwap(int[] nums1, int[] nums2) { int n
  • Mybatis结果集映射与生命周期介绍

    Mybatis结果集映射与生命周期介绍
    一、ResultMap结果集映射 1、设计思想 对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了 2、resultMap的应用场
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计