javaweb学习总结(九)—— 通过Servlet生成验证码图片(转)

时间:2023-03-09 08:02:23
javaweb学习总结(九)—— 通过Servlet生成验证码图片(转)

(每天都会更新至少一篇以上,有兴趣的可以关注)转载自孤傲苍狼

一、BufferedImage类介绍

生成验证码图片主要用到了一个BufferedImage类,如下:

aaarticlea/png;base64,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" alt="" />

创建一个DrawImage Servlet,用来生成验证码图片

  1 package gacl.response.study;
2 import java.awt.Color;
3 import java.awt.Font;
4 import java.awt.Graphics;
5 import java.awt.Graphics2D;
6 import java.awt.image.BufferedImage;
7 import java.io.IOException;
8 import java.util.Random;
9 import javax.imageio.ImageIO;
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 /**
15 * 生成随机图片,用来作为验证码
16 */
17 public class DrawImage extends HttpServlet {
18 private static final long serialVersionUID = 3038623696184546092L;
19
20 public static final int WIDTH = 120;//生成的图片的宽度
21 public static final int HEIGHT = 30;//生成的图片的高度
22
23 public void doGet(HttpServletRequest request, HttpServletResponse response)
24 throws ServletException, IOException {
25 this.doPost(request, response);
26 }
27
28 public void doPost(HttpServletRequest request, HttpServletResponse response)
29 throws ServletException, IOException {
30 String createTypeFlag = request.getParameter("createTypeFlag");//接收客户端传递的createTypeFlag标识
31 //1.在内存中创建一张图片
32 BufferedImage bi = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
33 //2.得到图片
34 Graphics g = bi.getGraphics();
35 //3.设置图片的背影色
36 setBackGround(g);
37 //4.设置图片的边框
38 setBorder(g);
39 //5.在图片上画干扰线
40 drawRandomLine(g);
41 //6.写在图片上随机数
42 //String random = drawRandomNum((Graphics2D) g,"ch");//生成中文验证码图片
43 //String random = drawRandomNum((Graphics2D) g,"nl");//生成数字和字母组合的验证码图片
44 //String random = drawRandomNum((Graphics2D) g,"n");//生成纯数字的验证码图片
45 //String random = drawRandomNum((Graphics2D) g,"l");//生成纯字母的验证码图片
46 String random = drawRandomNum((Graphics2D) g,createTypeFlag);//根据客户端传递的createTypeFlag标识生成验证码图片
47 //7.将随机数存在session中
48 request.getSession().setAttribute("checkcode", random);
49 //8.设置响应头通知浏览器以图片的形式打开
50 response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg");
51 //9.设置响应头控制浏览器不要缓存
52 response.setDateHeader("expries", -1);
53 response.setHeader("Cache-Control", "no-cache");
54 response.setHeader("Pragma", "no-cache");
55 //10.将图片写给浏览器
56 ImageIO.write(bi, "jpg", response.getOutputStream());
57 }
58
59 /**
60 * 设置图片的背景色
61 * @param g
62 */
63 private void setBackGround(Graphics g) {
64 // 设置颜色
65 g.setColor(Color.WHITE);
66 // 填充区域
67 g.fillRect(0, 0, WIDTH, HEIGHT);
68 }
69
70 /**
71 * 设置图片的边框
72 * @param g
73 */
74 private void setBorder(Graphics g) {
75 // 设置边框颜色
76 g.setColor(Color.BLUE);
77 // 边框区域
78 g.drawRect(1, 1, WIDTH - 2, HEIGHT - 2);
79 }
80
81 /**
82 * 在图片上画随机线条
83 * @param g
84 */
85 private void drawRandomLine(Graphics g) {
86 // 设置颜色
87 g.setColor(Color.GREEN);
88 // 设置线条个数并画线
89 for (int i = 0; i < 5; i++) {
90 int x1 = new Random().nextInt(WIDTH);
91 int y1 = new Random().nextInt(HEIGHT);
92 int x2 = new Random().nextInt(WIDTH);
93 int y2 = new Random().nextInt(HEIGHT);
94 g.drawLine(x1, y1, x2, y2);
95 }
96 }
97
98 /**
99 * 画随机字符
100 * @param g
101 * @param createTypeFlag
102 * @return
103 * String... createTypeFlag是可变参数,
104 * Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。注意:可变参数必须位于最后一项
105 */
106 private String drawRandomNum(Graphics2D g,String... createTypeFlag) {
107 // 设置颜色
108 g.setColor(Color.RED);
109 // 设置字体
110 g.setFont(new Font("宋体", Font.BOLD, 20));
111 //常用的中国汉字
112 String baseChineseChar = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6";
113 //数字和字母的组合
114 String baseNumLetter = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ";
115 //纯数字
116 String baseNum = "0123456789";
117 //纯字母
118 String baseLetter = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
119 //createTypeFlag[0]==null表示没有传递参数
120 if (createTypeFlag.length > 0 && null != createTypeFlag[0]) {
121 if (createTypeFlag[0].equals("ch")) {
122 // 截取汉字
123 return createRandomChar(g, baseChineseChar);
124 }else if (createTypeFlag[0].equals("nl")) {
125 // 截取数字和字母的组合
126 return createRandomChar(g, baseNumLetter);
127 }else if (createTypeFlag[0].equals("n")) {
128 // 截取数字
129 return createRandomChar(g, baseNum);
130 }else if (createTypeFlag[0].equals("l")) {
131 // 截取字母
132 return createRandomChar(g, baseLetter);
133 }
134 }else {
135 // 默认截取数字和字母的组合
136 return createRandomChar(g, baseNumLetter);
137 }
138
139 return "";
140 }
141
142 /**
143 * 创建随机字符
144 * @param g
145 * @param baseChar
146 * @return 随机字符
147 */
148 private String createRandomChar(Graphics2D g,String baseChar) {
149 StringBuffer sb = new StringBuffer();
150 int x = 5;
151 String ch ="";
152 // 控制字数
153 for (int i = 0; i < 4; i++) {
154 // 设置字体旋转角度
155 int degree = new Random().nextInt() % 30;
156 ch = baseChar.charAt(new Random().nextInt(baseChar.length())) + "";
157 sb.append(ch);
158 // 正向角度
159 g.rotate(degree * Math.PI / 180, x, 20);
160 g.drawString(ch, x, 20);
161 // 反向角度
162 g.rotate(-degree * Math.PI / 180, x, 20);
163 x += 30;
164 }
165 return sb.toString();
166 }
167 }

运行结果如下:

  javaweb学习总结(九)—— 通过Servlet生成验证码图片(转)

二、在Form表单中使用验证码图片

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
3 <html>
4 <head>
5 <title>在Form表单中使用验证码</title>
6 <script type="text/javascript">
7 //刷新验证码
8 function changeImg(){
9 document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/servlet/DrawImage?"+Math.random();
10 }
11 </script>
12 </head>
13
14 <body>
15 <form action="${pageContext.request.contextPath}/servlet/CheckServlet" method="post">
16 验证码:<input type="text" name="validateCode"/>
17 <img alt="验证码看不清,换一张" src="${pageContext.request.contextPath}/servlet/DrawImage" id="validateCodeImg" onclick="changeImg()">
18 <a href="javascript:void(0)" onclick="changeImg()">看不清,换一张</a>
19 <br/>
20 <input type="submit" value="提交">
21 </form>
22 </body>
23 </html> 

运行结果:

  javaweb学习总结(九)—— 通过Servlet生成验证码图片(转)

  DrawImage Servlet除了可以生成的字母和数字的组合的验证码图片之外,还可以生成汉字,纯数字,纯字母的验证码图片,只需要向DrawImage Servlet传递约定好的生成标识符参数即可,如下所示:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
3 <html>
4 <head>
5 <title>在Form表单中使用验证码</title>
6 <script type="text/javascript">
7 //刷新验证码
8 function changeImg(obj,createTypeFlag){
9 document.getElementById(obj.id).src="${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag="+createTypeFlag+"&"+Math.random();
10 }
11 </script>
12 </head>
13
14 <body>
15 <form action="${pageContext.request.contextPath}/servlet/CheckServlet" method="post">
16 数字字母混合验证码:<input type="text" name="validateCode"/>
17 <img alt="验证码看不清,换一张" src="${pageContext.request.contextPath}/servlet/DrawImage" id="validateCodeImg1" onclick="changeImg(this,'nl')">
18 <br/>
19 中文验证码:<input type="text" name="validateCode"/>
20 <img alt="验证码看不清,换一张" src="${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag=ch" id="validateCodeImg2" onclick="changeImg(this,'ch')">
21 <br/>
22 英文验证码:<input type="text" name="validateCode"/>
23 <img alt="验证码看不清,换一张" src="${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag=l" id="validateCodeImg3" onclick="changeImg(this,'l')">
24 <br/>
25 数字验证码:<input type="text" name="validateCode"/>
26 <img alt="验证码看不清,换一张" src="${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag=n" id="validateCodeImg4" onclick="changeImg(this,'n')">
27 <br/>
28 <input type="submit" value="提交">
29 </form>
30 </body>
31 </html>
javaweb学习总结(九)—— 通过Servlet生成验证码图片(转)

运行结果如下:

  aaarticlea/png;base64,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" alt="" />

三、服务器端对form表单提交上来的验证码处理

javaweb学习总结(九)—— 通过Servlet生成验证码图片(转)
 1 package gacl.response.study;
2 import java.io.IOException;
3 import javax.servlet.ServletException;
4 import javax.servlet.http.HttpServlet;
5 import javax.servlet.http.HttpServletRequest;
6 import javax.servlet.http.HttpServletResponse;
7 /**
8 * @author gacl
9 * 服务器端接收到验证码后的处理
10 */
11 public class CheckServlet extends HttpServlet {
12 public void doGet(HttpServletRequest request, HttpServletResponse response)
13 throws ServletException, IOException {
14 String clientCheckcode = request.getParameter("validateCode");//接收客户端浏览器提交上来的验证码
15 String serverCheckcode = (String) request.getSession().getAttribute("checkcode");//从服务器端的session中取出验证码
16 if (clientCheckcode.equals(serverCheckcode)) {//将客户端验证码和服务器端验证比较,如果相等,则表示验证通过
17 System.out.println("验证码验证通过!");
18 }else {
19 System.out.println("验证码验证失败!");
20 }
21 }
22
23 public void doPost(HttpServletRequest request, HttpServletResponse response)
24 throws ServletException, IOException {
25 doGet(request, response);
26 }
27
28 }