您的位置:首页 > 其它

使用 Servlet 生成图片验证码

2018-01-29 11:45 274 查看

原理

服务器生成一个包含随机的字符串的图片发给客户端,客户端提交数据时需要填写字符串作为验证。在服务器端,字符串保存在 session 中,当获取到客户端上传的字符串参数时,对比是否相等。

运行结果图:



实现

生成图片验证码的 Servlet 类

package cn.joker.servlet;

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

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

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
* Servlet implementation class IdentityServlet
*/
@WebServlet(description = "response生成图片验证码", urlPatterns = { "/IdentityServlet" })
public class IdentityServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//随机字符
private static final char[] CHARS = {'2','3','4','5','6','7','8','9','A','B','C','D',
'E','F','G','H','I','J'};
//随机数
private  Random random = new Random();

/**
* @see HttpServlet#HttpServlet()
*/
public IdentityServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
// 设置输出类型

response.setContentType("image/jpeg");
response.setDateHeader("expries", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
// 获取随机字符串
String randomString = getRandomString();
//System.out.println(randomString);
// 放到session 中
request.getSession(true).setAttribute("randomString", randomString);

// 图片的宽度、高度
int width = 100,height=30;
//用于背景色
Color color = getRandomColor();
// 用于前景色
Color reverse = getReverseColor(color);

// 创建一个彩色图片
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
// 获取绘图对象
Graphics2D g = bi.createGraphics();
g.setFont(new Font(Font.SANS_SERIF ,Font.BOLD,16));
g.setColor(color);
g.fillRect(0, 0, width, height);
g.setColor(reverse);
g.drawString(randomString, 18, 20);
// 绘制噪声点
for(int i = 0,n = random.nextInt(100);i<n;i++) {
g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);
}
/*  方法一:
* ServletOutputStream out = response.getOutputStream();
// 转成JPEG格式
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
// 对图片进行编码
encoder.encode(bi);
out.flush();*/
ImageIO.write(bi, "jpg", response.getOutputStream());

}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}

/**
* 获取六位随机字符
*/
public String getRandomString() {
StringBuffer buffer = new StringBuffer();
for(int i = 0; i<6;i++) {
buffer.append(CHARS[random.nextInt(18)]);
}
return buffer.toString();
}

/**
* 获取随机颜色
*/
public  Color getRandomColor() {
return new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255));
}

/**
* 获取某颜色的反色
*/
public  Color getReverseColor(Color c) {
return new Color(255-c.getRed(),255-c.getGreen(),255-c.getBlue());
}

}


显示界面(作为首页使用)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图片验证</title>
<script type="text/javascript">
function reloadImage(){

document.getElementById('btn').disabled = true;
//实时更新,保证每次都从服务器重新请求数据
document.getElementById('identity').src = '/ServletStudy/IdentityServlet?ts='+new Date().getTime();

}
</script>
</head>
<body>
<img alt="验证码" src="/ServletStudy/IdentityServlet" id="identity" onload="btn.disabled = false;" />
<input type="button" id="btn" value="换个图片" onclick="reloadImage()">
<form action="/ServletStudy/CheckIdentity" method="post">
验证码: <input type="text" name="check">
<input type="submit" value="提交">
</form>
</body>
</html>


校验验证码的 Servlet

package cn.joker.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 CheckIdentity
*/
@WebServlet(description = "校验验证码", urlPatterns = { "/CheckIdentity" })
public class CheckIdentity extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public CheckIdentity() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// 获取客户端上传的数据
String ch = request.getParameter("check");
// 获取session 中保存的数据
String id = (String) request.getSession().getAttribute("randomString");
if(ch.equals(id))
response.getWriter().append("<!DOCTYPE html>\r\n" +
"<html>\r\n" +
"<head>\r\n" +
"<meta charset=\"UTF-8\"></head>\r\n" +
"<body>").append("验证码通过").append("</body>\r\n" +
"</html>");
else
response.getWriter().append("<!DOCTYPE html>\r\n" +
"<html>\r\n" +
"<head>\r\n" +
"<meta charset=\"UTF-8\"></head>\r\n" +
"<body>").append("验证码错误").append("</body>\r\n" +
"</html>");

}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}

}


只要正确设定 response 输出类型及输出流,就能输出很多的格式数据,例如Excel、PDF、Word、MP3等。不同的输出类型需要声明不同的 Content-Type 属性,例如JPG图片是 “image/jpeg”,Word 则是 “application/msword”。

代码及内容大部分来源于Java Web 整合开发 王者归来
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: