一、BufferedImage类介绍

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

创建一个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 }

运行结果如下:

  

二、在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>

运行结果:

  

  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>

运行结果如下:

  

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

 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 }

avaweb学习总结(九)—— 通过Servlet生成验证码图片相关推荐

  1. javaweb(九)—— 通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片 1 package gacl.r ...

  2. 转: 通过Servlet生成验证码图片

    孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(九)-- 通过Servlet生成验证码图片 一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedIma ...

  3. javaweb学习总结(九):通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片 1 package gacl.r ...

  4. Java Web学习总结(6)——通过Servlet生成验证码图片

    2019独角兽企业重金招聘Python工程师标准>>> 一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawIma ...

  5. java web 生成验证码_Javaweb开发中通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片 package gacl.res ...

  6. 通过Servlet生成验证码图片

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片 package gacl.res ...

  7. 通过Servlet生成验证码图片 (转孤傲苍狼)

    一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedImage类,如下: 创建一个DrawImage Servlet,用来生成验证码图片 1 package gacl.r ...

  8. JavaWeb总结之通过Servlet生成验证码图片

    项目地址:https://github.com/zhangzeminzZ/ServletStudy 目录 1.BufferedImage类介绍 2.在Form表单中使用验证码图片 3.服务器端对for ...

  9. J2EE如何生成验证码图片和点击刷新验证码

    验证码图片生成步骤 创建BufferedImage对象. 获取BufferedImage的画笔,即调用getGraphics()方法获取Graphics对象. 调用Graphics对象的setColo ...

最新文章

  1. 王思聪语录 - CV版
  2. R语言ggplot2可视化绘制分组水平条形图并在条形图的各种位置添加数值标签实战
  3. nginx 日志切割
  4. 白话Elasticsearch67-不随意调节jvm和thread pool的原因jvm和服务器内存分配的最佳实践
  5. Serverless那么火,2019年的采用如何?
  6. 《Python Cookbook 3rd》笔记(2.2):字符串开头或结尾匹配
  7. mysql与django交互_django与mysql交互
  8. 信息学奥赛一本通 1055:判断闰年 | OpenJudge NOI 1.4 17
  9. explain分析SQL查询
  10. hibernate笔记(一)
  11. Selenium +Java自动化环境安装
  12. sql自动生成编码函数
  13. fedora python3-mysql_centos 下安装python3 的MySQLdb
  14. mysql存emoji_MySql存储emoji表情报错的处理方法
  15. vue2.x 父组件监听子组件事件并传回信息
  16. PAL文件(Palette,调色板)及格式
  17. DTW算法Python实现
  18. 虚拟机更改ip失败及没有虚拟网卡
  19. 原型设计工具Axure
  20. 华为P40与周冬雨排列

热门文章

  1. 线性代数——矩阵乘积的代码实现
  2. 智能家居市场风起云涌
  3. 图像处理——SURF算法
  4. spring 通过配置向quartz 注入service
  5. Maya动画导入UE4相关的细节问题及解决方案
  6. 基于Web的网上化妆品店
  7. PHP 程序设计之字符连接符
  8. 使用Samba实现Windows与Linux主机之间文件共享
  9. R和Rstudio中包的安装、加载和查看等操作
  10. 【转】ipad死机了,无法退出,也无法关机,怎么办