Servlet仿CSDN动态验证码的生成-带数字和字母

一、实现的思路:

(1)首先,需要创建一个Servlet。该Servlet通过字节型响应给客户端返回一个图片,该图片是通过JDK中Java 2D的类库来生成一个图片。图片的生成是依靠一个随机数来完成,然后将这个随机数写成图片格式。最后在Session将这个随机的字符串的状态保持住,以便在用户填写后进行对比。 
(2)其次,在需要加入验证码的JSP页面中,通过<img src="生成验证码图片的URI"/>引入该图片。 

(3)最后,单用户填写完验证码后,提交到某一个Servlet中。在这个Servlet中,通过request.getParameter()方法获取用户添加的验证码,然后取出后与Session中生成的验证码进行对比,如果对比成功就表示通过,否则返回该页面给用户提示验证码错误的信息。

(4)然后如果要仿CSDN动态验证码,就要分别生成数字和符号(+,-,*),根据符号,计算结果,计算中文,把结果存储到一个List<String>中去。

先来看看效果:

 

二、代码

这里首先实现只有数字和字母的,还不带符号运算

项目一下载

1、工程整体结构 

2、生成带数字和图片的代码

AuthCode.java

 

[java] view plain copy
 
  1. package com.mucfc;  
  2. import java.awt.Color;  
  3. import java.awt.Graphics;  
  4. import java.awt.Font;  
  5. import java.awt.image.BufferedImage;  
  6. import java.util.Random;  
  7.   
  8. /** 
  9.  * 生成验证码图片 
  10.  * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka) 
  11.  * @since 2015.6.22 
  12.  */  
  13. public class AuthCode {  
  14.     public static final int AUTHCODE_LENGTH = 5; // 验证码长度  
  15.     public static final int SINGLECODE_WIDTH = 15; // 单个验证码宽度  
  16.     public static final int SINGLECODE_HEIGHT = 30; // 单个验证码高度  
  17.     public static final int SINGLECODE_GAP = 4; // 单个验证码之间间隔  
  18.     public static final int IMG_WIDTH = AUTHCODE_LENGTH * (SINGLECODE_WIDTH + SINGLECODE_GAP);  
  19.     public static final int IMG_HEIGHT = SINGLECODE_HEIGHT;  
  20.     public static final char[] CHARS = {'0','1', '2', '3', '4', '5', '6', '7', '8',  
  21.         '9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',  
  22.         'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',  
  23.         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',  
  24.         'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };  
  25.     static Random random = new Random();  
  26.       
  27.     /** 
  28.      * 返回图片中的数字 
  29.      * @return String 
  30.      */  
  31.     public static String getAuthCode() {  
  32.         StringBuffer buffer = new StringBuffer();  
  33.         for (int i = 0; i < 5; i++) {// 生成6个字符  
  34.             buffer.append(CHARS[random.nextInt(CHARS.length)]);  
  35.         }  
  36.         return buffer.toString();  
  37.     }  
  38.       
  39.      /** 
  40.      * 返回带数字的图片 
  41.      * @return BufferedImage 
  42.      */  
  43.     public static BufferedImage getAuthImg(String authCode) {  
  44.         // 设置图片的高、宽、类型  
  45.         // RGB编码:red、green、blue  
  46.         BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,  
  47.                 BufferedImage.TYPE_INT_BGR);  
  48.         // 得到图片上的一个画笔  
  49.         Graphics g = img.getGraphics();  
  50.         // 设置画笔的颜色,用来做背景色  
  51.         g.setColor(Color.RED);  
  52.         // 用画笔来填充一个矩形,矩形的左上角坐标,宽,高  
  53.         g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);  
  54.         // 将画笔颜色设置为黑色,用来写字  
  55.         g.setColor(Color.BLACK);  
  56.         // 设置字体:宋体、不带格式的、字号  
  57.         g.setFont(new Font("宋体", Font.PLAIN, SINGLECODE_HEIGHT + 5));  
  58.         // 输出数字  
  59.         char c;  
  60.         for (int i = 0; i < authCode.toCharArray().length; i++) {  
  61.             // 取到对应位置的字符  
  62.             c = authCode.charAt(i);  
  63.             // 画出一个字符串:要画的内容,开始的位置,高度  
  64.             g.drawString(c + "", i * (SINGLECODE_WIDTH + SINGLECODE_GAP)  
  65.                     + SINGLECODE_GAP / 2, IMG_HEIGHT);  
  66.         }  
  67.         Random random = new Random();  
  68.         // 干扰素  
  69.         for (int i = 0; i < 15; i++) {  
  70.             int x = random.nextInt(IMG_WIDTH);  
  71.             int y = random.nextInt(IMG_HEIGHT);  
  72.             int x2 = random.nextInt(IMG_WIDTH);  
  73.             int y2 = random.nextInt(IMG_HEIGHT);  
  74.             g.drawLine(x, y, x + x2, y + y2);  
  75.         }  
  76.         return img;  
  77.     }  
  78. }  

 

在这里还可以自己更改图片的背景色、验证码的个数、干扰素强度等,有兴趣的同学自己好好设置下吧
3、生成动态验证码的servlet

getAuthCodeServlet.java

 

[java] view plain copy
 
  1. package com.mucfc;  
  2. import java.io.IOException;  
  3. import javax.imageio.ImageIO;  
  4. import javax.servlet.ServletException;  
  5. import javax.servlet.http.HttpServlet;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. /** 
  10.  * 得到生成验证码图片的servlet 
  11.  * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka) 
  12.  * @since 2015.6.22 
  13.  */  
  14. public class getAuthCodeServlet extends HttpServlet {  
  15.   
  16.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  17.             throws ServletException, IOException {  
  18.   
  19.          String authCode = AuthCode.getAuthCode();    
  20.            
  21.             request.getSession().setAttribute("authCode", authCode);    //将验证码保存到session中,便于以后验证    
  22.                 
  23.             try {    
  24.                 //发送图片    
  25.                 ImageIO.write(AuthCode.getAuthImg(authCode), "JPEG", response.getOutputStream());    
  26.             } catch (IOException e){    
  27.                 e.printStackTrace();    
  28.             }    
  29.           
  30.     }  
  31.   
  32.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  33.             throws ServletException, IOException {  
  34.   
  35.         doGet(request,response);  
  36.     }  
  37.   
  38. }  

4、index调用,并进行输入正确的判断

 

 

[html] view plain copy
 
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.     
  7.   
  8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  9. <html>  
  10.   <head>  
  11.     <base href="<%=basePath%>">  
  12.       
  13.     <title>My JSP 'index.jsp' starting page</title>  
  14.     <meta http-equiv="pragma" content="no-cache">  
  15.     <meta http-equiv="cache-control" content="no-cache">  
  16.     <meta http-equiv="expires" content="0">      
  17.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  18.     <meta http-equiv="description" content="This is my page">  
  19.     <!-- 
  20.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  21.     -->  
  22.   </head>  
  23.     
  24.   <body>  
  25.     <form action="index.jsp" method="post">    
  26.         <img src="servlet/GetAuthCodeServlet" id="authImg"/><href="#" onClick="window.location.reload()">看不清</a><br>    
  27.         <input type="text" name="inputCode">  
  28.         <%    
  29.     String inputCode = (String)request.getParameter("inputCode");    
  30.     String authCode = (String)session.getAttribute("authCode");    
  31.     if(inputCode!=null){  
  32.         if(authCode.equalsIgnoreCase(inputCode)){    
  33.             out.print("验证码正确!");    
  34.         }else{    
  35.             out.print("验证码错误!请重新输入!");    
  36.         }    
  37.         }    
  38. %>  
  39. <br>  
  40.         <input type="submit" value="提交">    
  41.     </form>     
  42.   </body>  
  43. </html>  

这里在直接都在一个jsp中判断了
5、web.xml设置

 

 

[html] view plain copy
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5"     
  3.     xmlns="http://java.sun.com/xml/ns/javaee"     
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  7.   
  8.     <servlet>  
  9.         <servlet-name>getAuthCodeServlet</servlet-name>  
  10.         <servlet-class>com.mucfc.getAuthCodeServlet</servlet-class>  
  11.     </servlet>  
  12.   
  13.     <servlet-mapping>  
  14.         <servlet-name>getAuthCodeServlet</servlet-name>  
  15.         <url-pattern>/servlet/GetAuthCodeServlet</url-pattern>  
  16.     </servlet-mapping>  
  17.   
  18.     <welcome-file-list>  
  19.         <welcome-file>index.html</welcome-file>  
  20.         <welcome-file>index.htm</welcome-file>  
  21.         <welcome-file>index.jsp</welcome-file>  
  22.         <welcome-file>default.html</welcome-file>  
  23.         <welcome-file>default.htm</welcome-file>  
  24.         <welcome-file>default.jsp</welcome-file>  
  25.     </welcome-file-list>  
  26. </web-app>  


6、运行效果

 

 

三、仿CSDN动态验证码实现

整个工程结构不变,

项目二下载

1、AuthCode改成如下

 

[java] view plain copy
 
  1. package com.mucfc;  
  2. import java.awt.Color;  
  3. import java.awt.Graphics;  
  4. import java.awt.Font;  
  5. import java.awt.image.BufferedImage;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8. import java.util.Random;  
  9.   
  10. /** 
  11.  * 生成验证码图片 
  12.  * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka) 
  13.  * @since 2015.6.22 
  14.  */  
  15. public class AuthCode {  
  16.     public static final int AUTHCODE_LENGTH = 5; // 验证码长度  
  17.     public static final int SINGLECODE_WIDTH = 20; // 单个验证码宽度  
  18.     public static final int SINGLECODE_HEIGHT = 30; // 单个验证码高度  
  19.     public static final int SINGLECODE_GAP = 4; // 单个验证码之间间隔  
  20.     public static final int IMG_WIDTH = AUTHCODE_LENGTH * (SINGLECODE_WIDTH + SINGLECODE_GAP);  
  21.     public static final int IMG_HEIGHT = SINGLECODE_HEIGHT;  
  22.     public static final char[] CHARS = {'0','1', '2', '3', '4', '5', '6', '7', '8', '9' };  
  23.     public static final char[] OPERATION={'+','-','*'};  
  24.       
  25.     static Random random = new Random();  
  26.       
  27.     /** 
  28.      * 返回图片中的数字 
  29.      * @return String 
  30.      */  
  31.     public static List<String> getAuthCode() {  
  32.   
  33.         char char1 = CHARS[random.nextInt(CHARS.length)];  
  34.         char char2 = CHARS[random.nextInt(CHARS.length)];  
  35.         char opt = OPERATION[random.nextInt(OPERATION.length)];  
  36.           
  37.         StringBuffer buffer = new StringBuffer();  
  38.         buffer.append(char1);  
  39.         buffer.append(getOperation(opt));  
  40.         buffer.append(char2);  
  41.           
  42.         String result=getResult(char1,char2,opt);  
  43.         List<String> list=new ArrayList<String>();    
  44.         list.add(buffer.toString());  
  45.         list.add(result);  
  46.         return list;  
  47.     }  
  48.       
  49.       /** 
  50.      * 返回计算的结果 
  51.      * @param operation 
  52.      * @return String 
  53.      */  
  54.     public static String getResult(char char1,char char2,char operation){     
  55.         int int1 = Integer.parseInt(String.valueOf(char1));  
  56.         int int2 = Integer.parseInt(String.valueOf(char2));  
  57.         if('+'==operation)  
  58.             return String.valueOf(int1+int2);  
  59.         else if ('-'==operation)  
  60.             return String.valueOf(int1-int2);  
  61.         else if ('*'==operation)  
  62.             return String.valueOf(int1*int2);  
  63.         else  
  64.         return null;  
  65.     }  
  66.       
  67.     /** 
  68.      * 返回符号对应的中文 
  69.      * @param operation 
  70.      * @return String 
  71.      */  
  72.     public static String getOperation(char operation){  
  73.         if('+'==operation)  
  74.             return "加上";  
  75.         else if ('-'==operation)  
  76.             return "减去";  
  77.         else if ('*'==operation)  
  78.             return "乘以";  
  79.         else  
  80.             return null;  
  81.     }  
  82.       
  83.      /** 
  84.      * 返回带数字的图片 
  85.      * @return BufferedImage 
  86.      */  
  87.     public static BufferedImage getAuthImg(String authCode) {  
  88.         // 设置图片的高、宽、类型  
  89.         // RGB编码:red、green、blue  
  90.         BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,  
  91.                 BufferedImage.TYPE_INT_BGR);  
  92.         // 得到图片上的一个画笔  
  93.         Graphics g = img.getGraphics();  
  94.         // 设置画笔的颜色,用来做背景色  
  95.         g.setColor(Color.YELLOW);  
  96.         // 用画笔来填充一个矩形,矩形的左上角坐标,宽,高  
  97.         g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);  
  98.         // 将画笔颜色设置为黑色,用来写字  
  99.         g.setColor(Color.BLACK);  
  100.         // 设置字体:宋体、不带格式的、字号  
  101.         g.setFont(new Font("宋体", Font.PLAIN, SINGLECODE_HEIGHT + 5));  
  102.         // 输出数字  
  103.         char c;  
  104.         for (int i = 0; i < authCode.toCharArray().length; i++) {  
  105.             // 取到对应位置的字符  
  106.             c = authCode.charAt(i);  
  107.             // 画出一个字符串:要画的内容,开始的位置,高度  
  108.             g.drawString(c + "", i * (SINGLECODE_WIDTH + SINGLECODE_GAP)  
  109.                     + SINGLECODE_GAP / 2, IMG_HEIGHT);  
  110.         }  
  111.         Random random = new Random();  
  112.         // 干扰素  
  113.         for (int i = 0; i < 5; i++) {  
  114.             int x = random.nextInt(IMG_WIDTH);  
  115.             int y = random.nextInt(IMG_HEIGHT);  
  116.             int x2 = random.nextInt(IMG_WIDTH);  
  117.             int y2 = random.nextInt(IMG_HEIGHT);  
  118.             g.drawLine(x, y, x + x2, y + y2);  
  119.         }  
  120.         return img;  
  121.     }  
  122. }  

2、getAuthCodeServlet改成如下

 

 

[java] view plain copy
 
  1. package com.mucfc;  
  2. import java.io.IOException;  
  3. import java.util.List;  
  4.   
  5. import javax.imageio.ImageIO;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. /** 
  12.  * 得到生成验证码图片的servlet 
  13.  * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka) 
  14.  * @since 2015.6.22 
  15.  */  
  16. public class getAuthCodeServlet extends HttpServlet {  
  17.   
  18.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  19.             throws ServletException, IOException {  
  20.   
  21.          List<String> list = AuthCode.getAuthCode();    
  22.            
  23.             request.getSession().setAttribute("authCode", list.get(1));    //将验证码保存到session中,便于以后验证    
  24.                 
  25.             try {    
  26.                 //发送图片    
  27.                 ImageIO.write(AuthCode.getAuthImg(list.get(0)), "JPEG", response.getOutputStream());    
  28.             } catch (IOException e){    
  29.                 e.printStackTrace();    
  30.             }    
  31.           
  32.     }  
  33.   
  34.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  35.             throws ServletException, IOException {  
  36.   
  37.         doGet(request,response);  
  38.     }  
  39.   
  40. }  

其它所有都不改变

 

运行后效果:

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

 

原文地址:http://blog.csdn.net/Evankaka/article/details/46597435

posted on   咚..咚  阅读(247)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示