您的位置:首页 > 其它

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

2017-07-11 09:20 381 查看
一、实现的思路:
(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

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

[java] view
plain copy

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调用,并进行输入正确的判断

[html] view
plain copy

<%@ 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设置

[html] view
plain copy

<?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动态验证码实现

整个工程结构不变,

项目二下载

1、AuthCode改成如下

[java] view
plain copy

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改成如下

[java] view
plain copy

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);

}

}

其它所有都不改变

运行后效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: