您的位置:首页 > 其它

使用Servlet生成验证码图片

2016-10-23 14:03 465 查看
使用Servlet生成验证码效果



实现原理

使用java.awt.image.BufferedImage创建图片

在图片上绘制验证信息(我这里写一个数学表达式)

在图片上添加干扰线

用Servlet控制响应头使浏览器以图片的方式打开

并设置浏览器不缓存当前文档

用ImageIO.write()方法输出

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
* Created by kay on 2016/10/21.
*/
@WebServlet(name = "ResponseImage3",urlPatterns = {"/responseimage3"})
public class ResponseImage3 extends HttpServlet {
public static final int WIDTH=120;
public static final int HEIGHT=30;

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_BGR);
Graphics g=image.getGraphics();
//背景
g.setColor(Color.white);
g.fillRect(0,0,WIDTH,HEIGHT);

//边框
g.setColor(Color.BLACK);
g.drawRect(1,1,WIDTH-2,HEIGHT
4000
-2);
drawRandomLine(g);
//生成随机数
Random random=new Random();
int a=random.nextInt(100);
int b=random.nextInt(100);
int sum=a+b;
Graphics2D g1=(Graphics2D)g;
g1.setColor(Color.BLACK);
g1.setFont(new Font(null,Font.ITALIC,20));
g1.drawString(a+"+"+b+"= ?",20,HEIGHT-5);
//将验证结果保存到Session中
request.getSession().setAttribute("checkcode1",sum+"");
//设置浏览器以图片格式输出
response.setContentType("image/jpeg");
//设置响应头控制浏览器不要缓存
response.setDateHeader("expries", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
//将图片写给浏览器
ImageIO.write(image, "jpg", response.getOutputStream());
}

//画几条随机的干扰线
private void drawRandomLine(Graphics g) {
// 设置颜色
g.setColor(Color.GREEN);
// 设置线条个数并画线
for (int i = 0; i < 5; i++) {
int x1 = new Random().nextInt(WIDTH);
int y1 = new Random().nextInt(HEIGHT);
int x2 = new Random().nextInt(WIDTH);
int y2 = new Random().nextInt(HEIGHT);
g.drawLine(x1, y1, x2, y2);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}


前台写一个Form表单用来验证

<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2016/10/21
Time: 17:41
To change this template use File | Settings | File Templates.
--%>
<%@ page import="java.util.*" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript">
//刷新验证码
function changeImg(){            document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/responseimage3?"+Math.random();
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath}/checkimage" method="post">
验证码:<input type="text" name="validateCode"/>
<img alt="验证码看不清,换一张" src="${pageContext.request.contextPath}/responseimage3" id="validateCodeImg" onclick="changeImg()">
<a href="javascript:void(0)" onclick="changeImg()">看不清,换一张</a>
<br/>
<input type="submit" value="提交">
</form>
</body>
</html>


注意:
function changeImg(){            document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/responseimage3?"+Math.random();
}


调用生成验证码图片的Servlet的时候传入一个随机的参数(Math.random),是为了与上一次的请求相区别,服务器对2次相同的请求会返回同一个结果,为了刷新图片那需要使用不同的请求。

提交验证码之后传到CheckImage这个servlet来检查是否输入正确

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

/**
* Created by kay on 2016/10/21.
*/
@WebServlet(name = "CheckImage",urlPatterns = {"/checkimage"})
public class CheckImage extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String clientCheckcode = request.getParameter("validateCode");//接收客户端浏览器提交上来的验证码
String serverCheckcode = (String) request.getSession().getAttribute("checkcode");//从服务器端的session中取出验证码

String checkcode1=(String) request.getSession().getAttribute("checkcode1");

if (clientCheckcode.equals(checkcode1)) {//将客户端验证码和服务器端验证比较,如果相等,则表示验证通过
System.out.println("验证码验证通过!");
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else {
System.out.println("验证码验证失败!");
response.sendRedirect(request.getContextPath()+"/failure.jsp");
}
}

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


到此这个小功能就完成了。点击图片更换验证码,输入结果进行验证。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: