博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Servlet仿CSDN动态验证码的生成-带数字和字母
阅读量:6634 次
发布时间:2019-06-25

本文共 10032 字,大约阅读时间需要 33 分钟。

原创作品。转载请注明出处

一、实现的思路:

(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+"/";%>                My JSP 'index.jsp' starting page	
看不清
<% 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设置

> <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
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
list=new ArrayList
(); 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
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); }}
其他全部都不改变

执行后效果:

原创作品。转载请注明出处

你可能感兴趣的文章