"It's that simple" Java realizes the generation and verification of verification codes

Everyone knows that in order to prevent our website from being maliciously attacked by some people and hackers, such as the registration page of our website, if we do not add a verification code box when the user registers, others can write a script to perform on your website. Malicious registration, such as registering your website n times per minute, your website will be attacked and crashed. When we add the verification code, when someone writes a script, they must first identify your verification code, but it is not so easy to identify the content in the image verification code, which can effectively prevent our website from being malicious Registration attack. Not much nonsense, just go to the code.

Tools for generating verification codes and verification code images

package com.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;

public class CodeUtil {
 private static int width = 90;// 定义图片的width
 private static int height = 20;// 定义图片的height
 private static int codeCount = 4;// 定义图片上显示验证码的个数
 private static int xx = 15;
 private static int fontHeight = 18;
 private static int codeY = 16;
 private static char[] codeSequence = { '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', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
 
 /**
 * 生成一个map集合
 * code为生成的验证码
 * codePic为生成的验证码BufferedImage对象
 * @return
 */
 public static Map<String,Object> generateCodeAndPic() {
 // 定义图像buffer
 BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 // Graphics2D gd = buffImg.createGraphics();
 // Graphics2D gd = (Graphics2D) buffImg.getGraphics();
 Graphics gd = buffImg.getGraphics();
 // 创建一个随机数生成器类
 Random random = new Random();
 // 将图像填充为白色
 gd.setColor(Color.WHITE);
 gd.fillRect(0, 0, width, height);

 // 创建字体,字体的大小应该根据图片的高度来定。
 Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
 // 设置字体。
 gd.setFont(font);

 // 画边框。
 gd.setColor(Color.BLACK);
 gd.drawRect(0, 0, width - 1, height - 1);

 // 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。
 gd.setColor(Color.BLACK);
 for (int i = 0; i < 30; i++) {
  int x = random.nextInt(width);
  int y = random.nextInt(height);
  int xl = random.nextInt(12);
  int yl = random.nextInt(12);
  gd.drawLine(x, y, x + xl, y + yl);
 }

 // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
 StringBuffer randomCode = new StringBuffer();
 int red = 0, green = 0, blue = 0;

 // 随机产生codeCount数字的验证码。
 for (int i = 0; i < codeCount; i++) {
  // 得到随机产生的验证码数字。
  String code = String.valueOf(codeSequence[random.nextInt(36)]);
  // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
  red = random.nextInt(255);
  green = random.nextInt(255);
  blue = random.nextInt(255);

  // 用随机产生的颜色将验证码绘制到图像中。
  gd.setColor(new Color(red, green, blue));
  gd.drawString(code, (i + 1) * xx, codeY);

  // 将产生的四个随机数组合在一起。
  randomCode.append(code);
 }
 Map<String,Object> map =new HashMap<String,Object>();
 //存放验证码
 map.put("code", randomCode);
 //存放生成的验证码BufferedImage对象
 map.put("codePic", buffImg);
 return map;
 }

 public static void main(String[] args) throws Exception {
 //创建文件输出流对象
 OutputStream out = new FileOutputStream("D://img/"+System.currentTimeMillis()+".jpg");
 Map<String,Object> map = CodeUtil.generateCodeAndPic();
 ImageIO.write((RenderedImage) map.get("codePic"), "jpeg", out);
 System.out.println("验证码的值为:"+map.get("code"));
 }
}

Next is an application demo based on jsp and servlet

1.jsp page code

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>验证码页面</title>
<script type="text/javascript"
 src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
</head>
<body>
 <form action="${pageContext.request.contextPath}/checkCode" method="post">
 请输入验证码:<input type="text" name="code" style="width: 80px;" /> <img id="imgObj" alt="验证码"
  src="${pageContext.request.contextPath}/getCode"><a href="#" onclick="changeImg()">换一张</a><br/> <input
  type="submit" value="提交" />
 </form>

</body>
<script type="text/javascript">
 $(function() {

 });

 function changeImg() { 
 var imgSrc = $("#imgObj"); 
 var src = imgSrc.attr("src"); 
 imgSrc.attr("src", chgUrl(src));
 }
 
 // 时间戳
 // 为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
 function chgUrl(url) {
 var timestamp = (new Date()).valueOf();
 url = url.substring(0, 20);
 if ((url.indexOf("&") >= 0)) {
  url = url + "×tamp=" + timestamp;
 } else {
  url = url + "?timestamp=" + timestamp;
 }
 return url;
 }

</script>
</html>

2. The servlet that generates the verification code in the background

package com.code;

import java.awt.image.RenderedImage;
import java.io.IOException;
import java.util.Map;

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 javax.servlet.http.HttpSession;

import com.utils.CodeUtil;

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

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 // 调用工具类生成的验证码和验证码图片
 Map<String, Object> codeMap = CodeUtil.generateCodeAndPic();

 // 将四位数字的验证码保存到Session中。
 HttpSession session = req.getSession();
 session.setAttribute("code", codeMap.get("code").toString());

 // 禁止图像缓存。
 resp.setHeader("Pragma", "no-cache");
 resp.setHeader("Cache-Control", "no-cache");
 resp.setDateHeader("Expires", -1);

 resp.setContentType("image/jpeg");

 // 将图像输出到Servlet输出流中。
 ServletOutputStream sos;
 try {
  sos = resp.getOutputStream();
  ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
  sos.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }

 }

}

3. The servlet to verify the verification code

package com.code;

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;
import javax.servlet.http.HttpSession;


@WebServlet("/checkCode")
public class CheckCode extends HttpServlet {
 private static final long serialVersionUID = 1L;

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

 }

 protected void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
 String code = request.getParameter("code");
 // 验证验证码
 String sessionCode = request.getSession().getAttribute("code").toString();
 if (code != null && !"".equals(code) && sessionCode != null && !"".equals(sessionCode)) {
  if (code.equalsIgnoreCase(sessionCode)) {
  response.getWriter().println("验证通过!");
  } else {
  response.getWriter().println("验证失败!");
  }
 } else {
  response.getWriter().println("验证失败!");
 }
 }

}

The above is the whole content of this article, I hope it will be helpful to everyone's study, and I hope everyone will support you

Guess you like

Origin blog.csdn.net/p1830095583/article/details/114392027