zoukankan      html  css  js  c++  java
  • Servlet仿CSDN动态验证码的生成-带数字和字母

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

    一、实现的思路:

    (1)首先,须要创建一个Servlet。该Servlet通过字节型响应给client返回一个图片。该图片是通过JDK中Java 2D的类库来生成一个图片。

    图片的生成是依靠一个随机数来完毕,然后将这个随机数写成图片格式。最后在Session将这个随机的字符串的状态保持住,以便在用户填写后进行对照。
    (2)其次,在须要加入验证码的JSP页面中,通过<img src="生成验证码图片的URI"/>引入该图片。

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

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


    先来看看效果:



    二、代码

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

    项目一下载

    1、project总体结构


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

    AuthCode.java

    package com.mucfc;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Font;
    import java.awt.image.BufferedImage;
    import java.util.Random;
    
    /**
     * 生成验证码图片
     * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka)
     * @since 2015.6.22
     */
    public class AuthCode {
    	public static final int AUTHCODE_LENGTH = 5; // 验证码长度
    	public static final int SINGLECODE_WIDTH = 15; // 单个验证码宽度
    	public static final int SINGLECODE_HEIGHT = 30; // 单个验证码高度
    	public static final int SINGLECODE_GAP = 4; // 单个验证码之间间隔
    	public static final int IMG_WIDTH = AUTHCODE_LENGTH * (SINGLECODE_WIDTH + SINGLECODE_GAP);
    	public static final int IMG_HEIGHT = SINGLECODE_HEIGHT;
    	public static final char[] CHARS = {'0','1', '2', '3', '4', '5', '6', '7', '8',
    		'9','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',
    		'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' };
    	static Random random = new Random();
    	
        /**
         * 返回图片中的数字
         * @return String
         */
    	public static String getAuthCode() {
    		StringBuffer buffer = new StringBuffer();
    		for (int i = 0; i < 5; i++) {// 生成6个字符
    			buffer.append(CHARS[random.nextInt(CHARS.length)]);
    		}
    		return buffer.toString();
    	}
    	
    	 /**
         * 返回带数字的图片
         * @return BufferedImage
         */
    	public static BufferedImage getAuthImg(String authCode) {
    		// 设置图片的高、宽、类型
    		// RGB编码:red、green、blue
    		BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
    				BufferedImage.TYPE_INT_BGR);
    		// 得到图片上的一个画笔
    		Graphics g = img.getGraphics();
    		// 设置画笔的颜色,用来做背景色
    		g.setColor(Color.RED);
    		// 用画笔来填充一个矩形,矩形的左上角坐标,宽。高
    		g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
    		// 将画笔颜色设置为黑色,用来写字
    		g.setColor(Color.BLACK);
    		// 设置字体:宋体、不带格式的、字号
    		g.setFont(new Font("宋体", Font.PLAIN, SINGLECODE_HEIGHT + 5));
    		// 输出数字
    		char c;
    		for (int i = 0; i < authCode.toCharArray().length; i++) {
    			// 取到相应位置的字符
    			c = authCode.charAt(i);
    			// 画出一个字符串:要画的内容,開始的位置,高度
    			g.drawString(c + "", i * (SINGLECODE_WIDTH + SINGLECODE_GAP)
    					+ SINGLECODE_GAP / 2, IMG_HEIGHT);
    		}
    		Random random = new Random();
    		// 干扰素
    		for (int i = 0; i < 15; i++) {
    			int x = random.nextInt(IMG_WIDTH);
    			int y = random.nextInt(IMG_HEIGHT);
    			int x2 = random.nextInt(IMG_WIDTH);
    			int y2 = random.nextInt(IMG_HEIGHT);
    			g.drawLine(x, y, x + x2, y + y2);
    		}
    		return img;
    	}
    }

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

    getAuthCodeServlet.java

    package com.mucfc;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 得到生成验证码图片的servlet
     * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka)
     * @since 2015.6.22
     */
    public class getAuthCodeServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		 String authCode = AuthCode.getAuthCode();  
             
    	        request.getSession().setAttribute("authCode", authCode);    //将验证码保存到session中。便于以后验证  
    	          
    	        try {  
    	            //发送图片  
    	            ImageIO.write(AuthCode.getAuthImg(authCode), "JPEG", response.getOutputStream());  
    	        } catch (IOException e){  
    	            e.printStackTrace();  
    	        }  
    	    
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		doGet(request,response);
    	}
    
    }
    
    4、index调用,并进行输入正确的推断

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
      
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'index.jsp' starting page</title>
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
      </head>
      
      <body>
        <form action="index.jsp" method="post">  
            <img src="servlet/GetAuthCodeServlet" id="authImg"/><a href="#" onClick="window.location.reload()">看不清</a><br>  
            <input type="text" name="inputCode">
            <%  
        String inputCode = (String)request.getParameter("inputCode");  
        String authCode = (String)session.getAttribute("authCode");  
        if(inputCode!=null){
            if(authCode.equalsIgnoreCase(inputCode)){  
                out.print("验证码正确!");  
            }else{  
                out.print("验证码错误!

    请又一次输入!"); } } %> <br> <input type="submit" value="提交"> </form> </body> </html>

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

    <?xml version="1.0" encoding="UTF-8"?

    > <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>getAuthCodeServlet</servlet-name> <servlet-class>com.mucfc.getAuthCodeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getAuthCodeServlet</servlet-name> <url-pattern>/servlet/GetAuthCodeServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>


    6、执行效果


    三、仿CSDN动态验证码实现

    整个project结构不变。

    项目二下载

    1、AuthCode改成例如以下

    package com.mucfc;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Font;
    import java.awt.image.BufferedImage;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    /**
     * 生成验证码图片
     * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka)
     * @since 2015.6.22
     */
    public class AuthCode {
    	public static final int AUTHCODE_LENGTH = 5; // 验证码长度
    	public static final int SINGLECODE_WIDTH = 20; // 单个验证码宽度
    	public static final int SINGLECODE_HEIGHT = 30; // 单个验证码高度
    	public static final int SINGLECODE_GAP = 4; // 单个验证码之间间隔
    	public static final int IMG_WIDTH = AUTHCODE_LENGTH * (SINGLECODE_WIDTH + SINGLECODE_GAP);
    	public static final int IMG_HEIGHT = SINGLECODE_HEIGHT;
    	public static final char[] CHARS = {'0','1', '2', '3', '4', '5', '6', '7', '8', '9' };
    	public static final char[] OPERATION={'+','-','*'};
    	
    	static Random random = new Random();
    	
        /**
         * 返回图片中的数字
         * @return String
         */
    	public static List<String> getAuthCode() {
    
    		char char1 = CHARS[random.nextInt(CHARS.length)];
    		char char2 = CHARS[random.nextInt(CHARS.length)];
    		char opt = OPERATION[random.nextInt(OPERATION.length)];
    	    
    		StringBuffer buffer = new StringBuffer();
    		buffer.append(char1);
    		buffer.append(getOperation(opt));
    		buffer.append(char2);
    		
    		String result=getResult(char1,char2,opt);
    		List<String> list=new ArrayList<String>();	
    		list.add(buffer.toString());
    		list.add(result);
    		return list;
    	}
    	
    	  /**
         * 返回计算的结果
         * @param operation
         * @return String
         */
    	public static String getResult(char char1,char char2,char operation){	
    		int int1 = Integer.parseInt(String.valueOf(char1));
    		int int2 = Integer.parseInt(String.valueOf(char2));
    		if('+'==operation)
    			return String.valueOf(int1+int2);
    		else if ('-'==operation)
    		    return String.valueOf(int1-int2);
    		else if ('*'==operation)
    		    return String.valueOf(int1*int2);
    		else
    		return null;
    	}
    	
        /**
         * 返回符号相应的中文
         * @param operation
         * @return String
         */
    	public static String getOperation(char operation){
    		if('+'==operation)
    			return "加上";
    		else if ('-'==operation)
    		    return "减去";
    		else if ('*'==operation)
    		    return "乘以";
    		else
    			return null;
    	}
    	
    	 /**
         * 返回带数字的图片
         * @return BufferedImage
         */
    	public static BufferedImage getAuthImg(String authCode) {
    		// 设置图片的高、宽、类型
    		// RGB编码:red、green、blue
    		BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
    				BufferedImage.TYPE_INT_BGR);
    		// 得到图片上的一个画笔
    		Graphics g = img.getGraphics();
    		// 设置画笔的颜色,用来做背景色
    		g.setColor(Color.YELLOW);
    		// 用画笔来填充一个矩形。矩形的左上角坐标,宽,高
    		g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
    		// 将画笔颜色设置为黑色,用来写字
    		g.setColor(Color.BLACK);
    		// 设置字体:宋体、不带格式的、字号
    		g.setFont(new Font("宋体", Font.PLAIN, SINGLECODE_HEIGHT + 5));
    		// 输出数字
    		char c;
    		for (int i = 0; i < authCode.toCharArray().length; i++) {
    			// 取到相应位置的字符
    			c = authCode.charAt(i);
    			// 画出一个字符串:要画的内容。開始的位置,高度
    			g.drawString(c + "", i * (SINGLECODE_WIDTH + SINGLECODE_GAP)
    					+ SINGLECODE_GAP / 2, IMG_HEIGHT);
    		}
    		Random random = new Random();
    		// 干扰素
    		for (int i = 0; i < 5; i++) {
    			int x = random.nextInt(IMG_WIDTH);
    			int y = random.nextInt(IMG_HEIGHT);
    			int x2 = random.nextInt(IMG_WIDTH);
    			int y2 = random.nextInt(IMG_HEIGHT);
    			g.drawLine(x, y, x + x2, y + y2);
    		}
    		return img;
    	}
    }
    2、getAuthCodeServlet改成例如以下

    package com.mucfc;
    import java.io.IOException;
    import java.util.List;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 得到生成验证码图片的servlet
     * @author 林炳文Evankaka(博客:http://blog.csdn.net/evankaka)
     * @since 2015.6.22
     */
    public class getAuthCodeServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		 List<String> list = AuthCode.getAuthCode();  
             
    	        request.getSession().setAttribute("authCode", list.get(1));    //将验证码保存到session中,便于以后验证  
    	          
    	        try {  
    	            //发送图片  
    	            ImageIO.write(AuthCode.getAuthImg(list.get(0)), "JPEG", response.getOutputStream());  
    	        } catch (IOException e){  
    	            e.printStackTrace();  
    	        }  
    	    
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		doGet(request,response);
    	}
    
    }
    
    其他全部都不改变

    执行后效果:


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

  • 相关阅读:
    PHP 中 parent、self、static、$this 的区别 & 后期静态绑定详解
    PHP中for和foreach背后发生了什么和关于迭代器的理解
    PHP中this,self,parent三个关键字
    PHP文件指针操作
    php中Session使用方法详解
    关于PHP日期时间的主要函数
    php获取checkbox复选框的多个选项的内容
    PHP中的11个魔术方法总结:__construct,、__destruct、__call等
    PHP类的自动加载机制实现方法分析
    C#学习笔记(二)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5224684.html
Copyright © 2011-2022 走看看