《J2EE学习笔记》之基于Servlet的图片验证码

1. 概述

什么是校验码?百度百科上的解释是,校验码(CAPTCHA),Completely Automated Public Turning test to tell Computers and Humans Apart(全自动区分计算机和人类的图灵测试),也就是要区分用户是计算机和人的程序。可防止:恶意破密码、刷票、论坛灌水,有效防止黑客对某一个特定注册用户用特定程序暴力破解方式尽心不断的登录尝试。
验证码分类:图片验证码、语音验证码、智力测试答题验证码等。一般在用户注册、登录网站时使用。

2. 要求

  • 图片的宽度高度、生成字符个数干扰线条数以及备选字符通过配置文件设置

3.示例代码结构图

这里写图片描述

4.代码详细

4.1 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Verify-Demo</display-name>
  <jsp-config>
    <jsp-property-group>
      <display-name>all</display-name>
      <url-pattern>*.jsp</url-pattern>
      <page-encoding>utf-8</page-encoding>
      <scripting-invalid>true</scripting-invalid>
    </jsp-property-group>
  </jsp-config>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
4.2 index.jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Verify Demo</title>
</head>
<body>
    <div>
        <form id="verifyForm" name="verifyForm" action="/Verify-Demo/VerifyCheckServlet" onsubmit="checkVerifyCode();" method="post">
            <div>
                <input type="text" id="verifyCode" name="verifyCode" style="height: 24px;">
                <img id="verifyImg" alt="验证码" src="/Verify-Demo/verifyServlet" onclick="changeVerifyImg();" style="vertical-align: middle;">
            </div>
            <div>
                <input type="submit" value="提交"/>
            </div>
        </form>
    </div>

    <script type="text/javascript">
        function checkVerifyCode() {
            var verifycode = document.getElementById("verifyCode").value.trim();
            if(verifycode == "") {
                alert("请输入验证码");
                return false;
            }           
        }

        function changeVerifyImg(){   
               var imgSrc = document.getElementById("verifyImg");     
               var src = imgSrc.src; 

                 // 为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳    
               var timestamp = (new Date()).valueOf();     
               if((src.indexOf("?")>=0)){         
                   src = src.substring(0, src.indexOf("?")) + "?timestamp=" + timestamp;     
               }else{
                   src = src+ "?timestamp=" + timestamp;
               } 

               imgSrc.src = src;     
        } 

    </script>
</body>
</html>
4.3 VerifyGetServlet.java
package com.smart.verify.servlet;

import java.awt.image.BufferedImage;
import java.io.IOException;

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

import com.smart.verify.util.VerifyUtil;

@WebServlet(name="verifycode", urlPatterns={"/verifyServlet"}, initParams={
        @WebInitParam(name="width", value="120"),
        @WebInitParam(name="height", value="30"),
        @WebInitParam(name="codeCount", value="4"),
        @WebInitParam(name="lineCount", value="10"),
        @WebInitParam(name="codeSequence", value="ABCDEFGhijkLMNopqRSTuvWxyZ0123456789")})
public class VerifyGetServlet extends HttpServlet {

    private static final long serialVersionUID = -5231875928635697722L;

    public VerifyGetServlet() {
        super();
    }

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int width = Integer.parseInt(getInitParameter("width"));   //图片宽度
        int height = Integer.parseInt(getInitParameter("height")); //图片高度 
        int codeCount = Integer.parseInt(getInitParameter("codeCount")); //验证码个数
        int lineCount = Integer.parseInt(getInitParameter("lineCount")); //干扰线条数
        String codeSequence = getInitParameter("codeSequence");          //验证码选择字符串

        //获取验证码
        String verifyCodes = VerifyUtil.getRand(codeCount, codeSequence);
        request.getSession().setAttribute("verify_code", verifyCodes);

        //获取验证码图片
        BufferedImage mapImg = VerifyUtil.getVerificationCode(width, height, lineCount, verifyCodes);

        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        ImageIO.write(mapImg, "jpeg", response.getOutputStream());
    }
}
4.4 VerifyUtil.java
package com.smart.verify.util;

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

public class VerifyUtil {

    /**
     * 生成检验码图片
     * @param width 图片宽度
     * @param height 图片高度
     * @param lineCount 干扰线的条数
     * @param codeCount 选择检验码个数
     * @param verifyCodes 备选字符串
     * */
    public static BufferedImage getVerificationCode(int width, int height, int lineCount, String verifyCodes) {
        //定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics2D g2d = buffImg.createGraphics();
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        //设置字体
        Font font = new Font("Fixedsys", Font.PLAIN, height-2);
        g2d.setFont(font);

        //画框线
        g2d.setColor(Color.BLACK);
        g2d.drawRect(0, 0, width-1, height-1);

        //画干扰线
        Random random = new Random();
        g2d.setColor(Color.BLACK);
        for(int i=lineCount; i>0; i--) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(12);
            int y1 = random.nextInt(12);
            g2d.drawLine(x, y, x+x1, y+y1);
        }

        //画检验码
        int x = width / (verifyCodes.length() + 1);
        for(int i=0; i<verifyCodes.length(); i++) {
            int red = random.nextInt(255);
            int green = random.nextInt(255);
            int blue = random.nextInt(255);
            g2d.setColor(new Color(red, green, blue));
            g2d.drawString(String.valueOf(verifyCodes.charAt(i)), (i+1)*x, height-4);
        }

        return buffImg;
    }

    /**
     * 获取检验码
     * @param codeCount 选择检验码个数
     * @param codeStr 备选字符串
     * */
    public static String getRand(int codeCount, String codeStr) {
        Random random = new Random();
        StringBuffer codes = new StringBuffer();
        for(int i=0;i<codeCount;i++){
            char c = codeStr.charAt(random.nextInt(codeStr.length()));
            codes.append(String.valueOf(c));
        }
        return codes.toString();        
    }
}
4.5 VerifyCheckServlet.java
package com.smart.verify.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 VerifyCheckServlet
 */
@WebServlet("/VerifyCheckServlet")
public class VerifyCheckServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public VerifyCheckServlet() {
        super();
    }

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String verifyCode = request.getParameter("verifyCode");
        String oldVerifyCode = (String) request.getSession().getAttribute("verify_code");

        System.out.println("oldVerifyCode="+oldVerifyCode +",verifyCode="+verifyCode);

        if(oldVerifyCode.equalsIgnoreCase(verifyCode)) {
            System.out.println("验证成功!");
            response.sendRedirect("success.jsp");
        }else {
            System.out.println("验证失败!");            
            response.sendRedirect("fail.jsp");
        }

    }

}

转载请注明出处:http://blog.csdn.net/shy_Angel/article/details/56836216

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
J2EE开发中,我们经常需要对字符串进行编码,以便在不同的系统之间传输数据时,能够正确地处理特殊字符。其中,URLEncoder.encode(String, enc)是一种常用的编码方式。 URLEncoder.encode()方法的作用是将指定的字符串进行编码,以便在URL中传输。它的语法如下: ``` public static String encode(String s, String enc) throws UnsupportedEncodingException ``` 其中,参数s是要编码的字符串,参数enc是指定字符集的名称,如果不指定,默认为UTF-8。 该方法的返回值是一个编码后的字符串。 例如,如果要将字符串“Hello World!”编码为UTF-8格式的字符串,可以使用以下代码: ``` String encodedStr = URLEncoder.encode("Hello World!", "UTF-8"); System.out.println(encodedStr); ``` 执行该代码后,输出结果为: ``` Hello+World%21 ``` 可以看到,空格被编码为“+”号,感叹号被编码为“%21”。 需要注意的是,如果字符串中包含特殊字符,如“&”、“=”等,也需要进行编码,否则在URL传输时会出现错误。例如,如果要将字符串“name=张三&age=18”编码为UTF-8格式的字符串,可以使用以下代码: ``` String encodedStr = URLEncoder.encode("name=张三&age=18", "UTF-8"); System.out.println(encodedStr); ``` 执行该代码后,输出结果为: ``` name%3D%E5%BC%A0%E4%B8%89%26age%3D18 ``` 可以看到,等号被编码为“%3D”,中文字符被编码为UTF-8格式的字符串。 总之,URLEncoder.encode()方法是J2EE开发中常用的编码方式,可以有效地处理特殊字符,确保数据在不同系统之间的传输正确无误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值