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

时间: 2024-10-25 02:40:48

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

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

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.实现的思路: (1)首先,需要创建一个Servlet.该Servlet通过字节型响应给客户端返回一个图片,该图片是通过JDK中Java 2D的类库来生成一个图片.图片的生成是依靠一个随机数来完成,然后将这个随机数写成图片格式.最后在Session将这个随机的字符串的状态保持住,以便在用户填写后进行对比. (2)其次,在需要加入验证码的JSP页面中,通过<img src="生成验证码

通过php生成纯数字、字母数字、图片、纯汉字的随机数验证码

现在讲开始通过PHP生成各种验证码旅途,新手要开车了,请刷卡! 首先,我们开始先生成一个放验证码的背景图片 注:没有Imagejpg()这个函数,只有imagepng()函数 imagecreatetruecolor()函数含义 效果 考虑到我们一般验证码的背景图片为白色,那么我们现在就把背景图片改一下 效果 相关函数意思 注:在输出图片之前,我们必须要生成header("Content-type:image/png"),即告诉服务器输出的是图片 一.生成纯数字验证码 1.产生数字的代

pyhton2 and python3 生成随机数字、字母、符号字典(用于撞库测试/验证码等)

本文介绍Python3中String模块ascii_letters和digits方法,其中ascii_letters是生成所有字母,从a-z和A-Z,digits是生成所有数字0-9.string.punctuation是所有标点'!"#$%&\'()*+,-./:;<=>[email protected][\\]^_`{|}~' String模块中的常量: string.digits:数字0~9 string.ascii_letters:所有字母(大小写) string.l

【Web】Java生成中文GIF动态验证码-集成SpringMVC

转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自[大学之旅_谙忆的博客] 说明 GIF验证码相对于JPG图片验证码来说,要更难破解一些,加大了破解的代价. 从昨天到现在,写了一个小小的GIF验证码项目(中文成语). 当然,你可以自己修改成字母数字的.我只是单纯的觉得中文验证码的破解代价更高一点~ 我在这里生成GIF图片的类,用到了国外牛人的三个类,也就是: AnimatedGifEncoder LZWEncoder 和NeuQuant,这三个类. 没办法

jsp使用servlet实现用户登录 及动态验证码

在进行表单设计中,验证码的增加恰恰可以实现是否为"人为"操作,增加验证码可以防止网站数据库信息的冗杂等... 现在,我将讲述通过servlet实现验证码: 验证码作为一个图片,在页面中为"画"出来的,它是如何画出来的呢? <生成图片> { 生成图片的类: 1.BufferedImage图像数据缓冲区 2.Graphics绘制图片 3.color获取颜色 4.Random获取随机数 5.ImageIO输出图片 } /////////////////////

利用 PIL模块实现生成动态验证码

简单说下需求: 当用户点击动态框时,实现实时更换动态库里的数字更换 模块: PIL  io 前端页面: <img src="/get_code/" id="id_img" width="260" height="35"> <script> $('#id_img').click(function () { let old_path = $('#id_img').attr('src'); $(this).a

Google动态验证码

Google动态验证码作用:可以动态的生成一个6位数的验证码,可以用于双重验证,增加网站的安全性. 条件:首先需要在手机上下载一个Google 验证器.(google authenticator app) 还需要在你的项目中引入一个Jar最主要的 <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1

JQuery仿最新淘宝网首页带箭头幻灯片,JQuery轮播图

JQuery代码 <script type="text/javascript"> $(function() { var $banner = $('.banner'); var $banner_ul = $('.banner-img'); var $btn = $('.banner-btn'); var $btn_a = $btn.find('a') var v_width = $banner.width(); var page = 1; var timer = null;

登录页面动态验证码的设置

登录页面动态验证码的设置 采用php中创建对象的思想进行动态验证码的设置 1.创建出一个背景图片,用来存放动态码输出位置 1 function createImage(){ 2 // 创建图片对象,并设置图片的宽高 imagecreatetruecolor 3 $this->image = imagecreatetruecolor($this->width, $this->height); 4 // 图片创建背景颜色 5 // rand(下界,上界), php中的随机数 6 $backg