zoukankan      html  css  js  c++  java
  • 使用Servlet实现验证码

    没有验证码带来的问题

    1. 对特定用户不断登录破解密码。
    2. 对某个网站创建账户。
    3. 对某个网站提交垃圾数据。
    4. 对某个网站刷票。

     通过验证码由用户肉眼识别其中的验证码信息,从而区分用户是人还是计算机。

    定义:

    • 验证码(CAPTCHA):是一种区分用户是计算机还是人的公共全自动程序。
    • 作用:防止恶意破解密码、刷票、论坛灌水,防止黑客暴力破解。

    使用Servlet实现验证码

        实现图片验证码类GenerateImageCodeServlet.java

    GenerateImageCodeServlet.java

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Date;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class GenerateImageCodeServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
    
        private static final char[] CH = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
        private static final int IMAGE_WIDTH = 73;
        private static final int IMAGE_HEIGHT = 28;
        private static final int LINE_NUM = 30;
        private static final int RANDOM_NUM = 4;
        Random random = new Random();
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setContentType("image/jpg");//设置相应类型,告诉浏览器输出的内容为图片
            response.setHeader("Pragma", "No-cache");//设置响应头信息,告诉浏览器不要缓存此内容
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expire", new Date().getTime());
            
            BufferedImage bi = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_BGR);
            Graphics g = bi.getGraphics();
            g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
            g.setColor(getRandomColor(110, 133));
            g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));
            // 绘制干扰线
            for (int i = 1; i <= LINE_NUM; i++) {
                int x = random.nextInt(IMAGE_WIDTH);
                int y = random.nextInt(IMAGE_HEIGHT);
                int xl = random.nextInt(13);
                int yl = random.nextInt(15);
                g.drawLine(x, y, x + xl, y + yl);
            }
    
            // 绘制随机字符
            StringBuilder sb = new StringBuilder();
            String str = null;
            for (int i = 0; i < RANDOM_NUM; i++) {
                g.setFont(new Font("Fixedsys", Font.CENTER_BASELINE, 18));
                g.setColor(new Color(random.nextInt(101), random.nextInt(111), random.nextInt(121)));
                str = CH[random.nextInt(CH.length)] + "";
                g.drawString(str, 13 * i, 16);
                g.translate(random.nextInt(3), random.nextInt(3));
                sb.append(str);
            }
            g.dispose();
            request.getSession().setAttribute("safeCode", sb.toString());
            ImageIO.write(bi, "JPG", response.getOutputStream());
        }
    
        /**
         * 获得颜色
         */
        private Color getRandomColor(int fc, int bc) {
            if (fc > 255)
                fc = 255;
            if (bc > 255)
                bc = 255;
            int r = fc + random.nextInt(bc - fc - 16);
            int g = fc + random.nextInt(bc - fc - 14);
            int b = fc + random.nextInt(bc - fc - 18);
            return new Color(r, g, b);
    
        }
    
    }

    登录验证LoginServlet.java

    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoginServlet extends HttpServlet{
    
        private static final long serialVersionUID = 1L;
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            
            resp.setContentType("text/html;charset=gbk");
            
            String safeCode = (String) req.getSession().getAttribute("safeCode");
            String checkcode = req.getParameter("checkcode");
            
            PrintWriter out = resp.getWriter();
            
            if (safeCode.equalsIgnoreCase(checkcode)) {
                out.println("验证码正确");
            } 
            else {
                out.println("验证码错误");
            }
            out.flush();
            out.close();
        }
        
    }

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    
        <servlet>
            <servlet-name>ImageCodeServlet</servlet-name>
            <servlet-class>com.lijy.servlet.GenerateImageCodeServlet</servlet-class>
        </servlet>
        
        <servlet>
            <servlet-name>LoginServlet</servlet-name>
            <servlet-class>com.lijy.servlet.LoginServlet</servlet-class>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>ImageCodeServlet</servlet-name>
            <url-pattern>/safe_code</url-pattern>
        </servlet-mapping>
    
        <servlet-mapping>
            <servlet-name>LoginServlet</servlet-name>
            <url-pattern>/login</url-pattern>
        </servlet-mapping>
    
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
        
    </web-app>

    index.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>checkcodes</title>
    <script type="text/javascript">
        function reloadCode() {
            var time = new Date().getTime();
            document.getElementById("imagecode").src="<%=request.getContextPath()%>/safe_code?d="+time;
        }
    </script>
    </head>
    <body>
    
    <form action="<%=request.getContextPath()%>/login" method="get">
    验证码:<input type="text" name="checkcode" />
        <img alt="验证码" id="imagecode" src="<%=request.getContextPath()%>/safe_code">
        <a href="javascript:reloadCode();">看不清楚</a><br/>
        <input type="submit" value="提交" />
    <hr>
    
    </form>
    
    </body>
    </html>

    页面截图

  • 相关阅读:
    前沿技术解密——VirtualDOM
    Ques核心思想——CSS Namespace
    Unix Pipes to Javascript Pipes
    Road to the future——伪MVVM库Q.js
    聊聊CSS postproccessors
    【译】十款性能最佳的压缩算法
    Kafka Streams开发入门(9)
    Kafka Streams开发入门(8)
    【译】Kafka Producer Sticky Partitioner
    【译】99th Percentile Latency at Scale with Apache Kafka
  • 原文地址:https://www.cnblogs.com/yewen1234/p/11103640.html
Copyright © 2011-2022 走看看