使用 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 整合开发 王者归来
相关文章推荐
- 使用Servlet生成图片验证码
- Java Web:使用Servlet生成网页随机图片验证码
- 使用servlet生成图片验证码
- Java生成登陆时使用的图片验证码
- 使用google.kaptcha来生成图片验证码的实现方法
- 10min搞定VerifyCodeServlet(生成一次性图片验证码)
- JfreeChart 生成工具和Servlet或者Action联合使用
- (七)利用servlet生成图片验证码
- servlet生成图片验证码
- 使用Servlet动态生成图片
- 使用zxing生成二维码 - servlet形式
- python使用pil生成图片验证码的方法
- 使用Java通过Servlet生成图片验证码
- 小工具(7):项目所需小工具之VerifyCodeServlet(生成一次性图片验证码)
- springmvc使用谷歌captcha生成图片验证码
- 使用Servlet生成验证码图片
- servlet生成图片验证码
- 使用struts2生成图片验证码并显示
- 使用java代码生成图片验证码
- 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现(spring MVC框架)。