林炳文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

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

  1. Django之动态验证码的生成

    kind.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

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

    现在讲开始通过PHP生成各种验证码旅途,新手要开车了,请刷卡! 首先,我们开始先生成一个放验证码的背景图片 注:没有Imagejpg()这个函数,只有imagepng()函数 imagecreatet ...

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

    本文介绍Python3中String模块ascii_letters和digits方法,其中ascii_letters是生成所有字母,从a-z和A-Z,digits是生成所有数字0-9.string.p ...

  4. 字母数字、字母、汉字验证码 (java)

    原文:http://blog.csdn.net/qh_java/article/details/49854477 一.字母数字,字母,汉字验证码的生成代码 1.字母数字验证码: package com ...

  5. Java基础之随机生成数字和字母

    字母与数字的ASCII码 目 前计算机中用得最广泛的 字符集及其编码,是由美国国家标准局(ANSI)制定的ASCII码(American Standard Code for Information I ...

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

    在进行表单设计中,验证码的增加恰恰可以实现是否为“人为”操作,增加验证码可以防止网站数据库信息的冗杂等... 现在,我将讲述通过servlet实现验证码: 验证码作为一个图片,在页面中为“画”出来的, ...

  7. C#之asp.net 及MVC 生成动态验证码:

    C#之asp.net 及MVC 生成动态验证码: 1.生成验证码字符串 // 随机生成指定长度的验证码字符串private string RandomCode(int length) { string ...

  8. .NET中生成动态验证码

    .NET中生成动态验证码 验证码是图片上写上几个字,然后对这几个字做特殊处理,如扭曲.旋转.修改文字位置,然后加入一些线条,或加入一些特殊效果,使这些在人类能正常识别的同时,机器却很难识别出来,以达到 ...

  9. php生成动态验证码 加减算法验证码 简单验证码

    预览效果: <?php /** *ImageCode 生成包含验证码的GIF图片的函数 *@param $string 字符串 *@param $width 宽度 *@param $height ...

随机推荐

  1. Python学习(一)-在VS上搭建开发环境

    1.到官网下载最新Python 注意:虽然目前大部分应用是Python2写的,但Python3必定会成为以后的主流 不管选择学习哪个,了解pyhton2和pyhton3的差异是必须的 2.安装Pyth ...

  2. Android开发笔记(9)——初步设置Menu

    转载请注明:http://www.cnblogs.com/igoslly/p/6858656.html   初步设置Menu   设置Menu,在ActionBar上添加按钮操作:         在 ...

  3. 关于类似vue-cli 脚手架

    #!/usr/bin/env node const download = require('download-git-repo') const program = require('commander ...

  4. servlet的多线程并发问题

    package gz.itcast.e_thread; import java.io.IOException; import javax.servlet.ServletException; impor ...

  5. css 众妙之门 学习笔记

    伪类: 结构伪类: :empty :only-child :before :after :active :hover :focus :link :visited :first-child :last- ...

  6. python基础--字符串操作、列表、元组、文件操作

    一.变量及条件判断 1.字符串.布尔类型.float.int类型,None都是不可变变量 2.字符串是不可变变量,不可变变量就是指定义之后不能修改它的值 3.count +=1和count=count ...

  7. 在把table表格中的数据导出到Excel的时候,以科学计数法显示位数多的数字时怎么解决?

    sbHtml.AppendFormat("<td> {0}</td>", data[i].IDcard.ToString()); sbHtml.Append ...

  8. Josephus problem(约瑟夫问题,丢手绢问题)

    约瑟夫问题 约瑟夫环问题是一个数学应用题:已知n个人(以编号1,2,3.....,n)围坐在一张圆桌的周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列 ...

  9. selenium之浏览器驱动

    selenium需要配合浏览器的驱动使用,几个主要的浏览器驱动如下 浏览器 链接 Chrome https://sites.google.com/a/chromium.org/chromedriver ...

  10. Enable ssh root login in Solaris

    1. Change the file /etc/ssh/sshd_config with PermitRootLogin yes to replace PermitRootLogin no 2. re ...