您的位置:首页 > 其它

《J2EE学习笔记》之基于Servlet的图片验证码

2017-02-24 11:51 513 查看

1. 概述

什么是校验码?百度百科上的解释是,校验码(CAPTCHA),Completely Automated Public Turning test to tell Computers and Humans Apart(全自动区分计算机和人类的图灵测试),也就是要区分用户是计算机和人的程序。可防止:恶意破密码、刷票、论坛灌水,有效防止黑客对某一个特定注册用户用特定程序暴力破解方式尽心不断的登录尝试。
验证码分类:图片验证码、语音验证码、智力测试答题验证码等。一般在用户注册、登录网站时使用。


2. 要求

图片的宽度高度、生成字符个数干扰线条数以及备选字符通过配置文件设置

3.示例代码结构图



4.代码详细

4.1 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Verify-Demo</display-name>
<jsp-config>
<jsp-property-group>
<display-name>all</display-name>
<url-pattern>*.jsp</url-pattern>
<page-encoding>utf-8</page-encoding>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


4.2 index.jsp

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Verify Demo</title>
</head>
<body>
<div>
<form id="verifyForm" name="verifyForm" action="/Verify-Demo/VerifyCheckServlet" onsubmit="checkVerifyCode();" method="post">
<div>
<input type="text" id="verifyCode" name="verifyCode" style="height: 24px;">
<img id="verifyImg" alt="验证码" src="/Verify-Demo/verifyServlet" onclick="changeVerifyImg();" style="vertical-align: middle;">
</div>
<div>
<input type="submit" value="提交"/>
</div>
</form>
</div>

<script type="text/javascript">
function checkVerifyCode() {
var verifycode = document.getElementById("verifyCode").value.trim();
if(verifycode == "") {
alert("请输入验证码");
return false;
}
}

function changeVerifyImg(){
var imgSrc = document.getElementById("verifyImg");
var src = imgSrc.src;

// 为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
var timestamp = (new Date()).valueOf();
if((src.indexOf("?")>=0)){
src = src.substring(0, src.indexOf("?")) + "?timestamp=" + timestamp;
}else{
src = src+ "?timestamp=" + timestamp;
}

imgSrc.src = src;
}

</script>
</body>
</html>


4.3 VerifyGetServlet.java

package com.smart.verify.servlet;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import ja
da2f
vax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.smart.verify.util.VerifyUtil;

@WebServlet(name="verifycode", urlPatterns={"/verifyServlet"}, initParams={
@WebInitParam(name="width", value="120"),
@WebInitParam(name="height", value="30"),
@WebInitParam(name="codeCount", value="4"),
@WebInitParam(name="lineCount", value="10"),
@WebInitParam(name="codeSequence", value="ABCDEFGhijkLMNopqRSTuvWxyZ0123456789")})
public class VerifyGetServlet extends HttpServlet {

private static final long serialVersionUID = -5231875928635697722L;

public VerifyGetServlet() {
super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = Integer.parseInt(getInitParameter("width"));   //图片宽度
int height = Integer.parseInt(getInitParameter("height")); //图片高度
int codeCount = Integer.parseInt(getInitParameter("codeCount")); //验证码个数
int lineCount = Integer.parseInt(getInitParameter("lineCount")); //干扰线条数
String codeSequence = getInitParameter("codeSequence");          //验证码选择字符串

//获取验证码
String verifyCodes = VerifyUtil.getRand(codeCount, codeSequence);
request.getSession().setAttribute("verify_code", verifyCodes);

//获取验证码图片
BufferedImage mapImg = VerifyUtil.getVerificationCode(width, height, lineCount, verifyCodes);

response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
ImageIO.write(mapImg, "jpeg", response.getOutputStream());
}
}


4.4 VerifyUtil.java

package com.smart.verify.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;

public class VerifyUtil {

/**
* 生成检验码图片
* @param width 图片宽度
* @param height 图片高度
* @param lineCount 干扰线的条数
* @param codeCount 选择检验码个数
* @param verifyCodes 备选字符串
* */
public static BufferedImage getVerificationCode(int width, int height, int lineCount, String verifyCodes) {
//定义图像buffer
BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = buffImg.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);

//设置字体
Font font = new Font("Fixedsys", Font.PLAIN, height-2);
g2d.setFont(font);

//画框线
g2d.setColor(Color.BLACK);
g2d.drawRect(0, 0, width-1, height-1);

//画干扰线
Random random = new Random();
g2d.setColor(Color.BLACK);
for(int i=lineCount; i>0; i--) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(12);
int y1 = random.nextInt(12);
g2d.drawLine(x, y, x+x1, y+y1);
}

//画检验码
int x = width / (verifyCodes.length() + 1);
for(int i=0; i<verifyCodes.length(); i++) {
int red = random.nextInt(255);
int green = random.nextInt(255);
int blue = random.nextInt(255);
g2d.setColor(new Color(red, green, blue));
g2d.drawString(String.valueOf(verifyCodes.charAt(i)), (i+1)*x, height-4);
}

return buffImg;
}

/**
* 获取检验码
* @param codeCount 选择检验码个数
* @param codeStr 备选字符串
* */
public static String getRand(int codeCount, String codeStr) {
Random random = new Random();
StringBuffer codes = new StringBuffer();
for(int i=0;i<codeCount;i++){
char c = codeStr.charAt(random.nextInt(codeStr.length()));
codes.append(String.valueOf(c));
}
return codes.toString();
}
}


4.5 VerifyCheckServlet.java

package com.smart.verify.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class VerifyCheckServlet
*/
@WebServlet("/VerifyCheckServlet")
public class VerifyCheckServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

public VerifyCheckServlet() {
super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String verifyCode = request.getParameter("verifyCode");
String oldVerifyCode = (String) request.getSession().getAttribute("verify_code");

System.out.println("oldVerifyCode="+oldVerifyCode +",verifyCode="+verifyCode);

if(oldVerifyCode.equalsIgnoreCase(verifyCode)) {
System.out.println("验证成功!");
response.sendRedirect("success.jsp");
}else {
System.out.println("验证失败!");
response.sendRedirect("fail.jsp");
}

}

}


转载请注明出处:http://blog.csdn.net/shy_Angel/article/details/56836216
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  验证码 j2ee servlet