Java实现验证码

时间:2021-09-25 16:59:55
 验证码虽然是降低了用户对软件(或者系统)的体验,产生的负面的影响,然而,验证码也有其必要的作用。验证码主要作用是区分了“机器”和“人”,在某些领域里,如果用“机器”去不断的注册账户或者登录账户,产生的弊端会很大。
如:购票网站,银行系统,网络购物,各大论坛。这些领域都在避免别人用“机器”去操作,所有使用验证码,增加了机器识别验证码 的难度,让真正的用户“人”去操作。

以下是具体的案例

Java实现验证码

环境和工具:
Myeclipse10_6
Tomcat7.x
jdk:myeclipse自带的jdk环境

index.jsp 如下

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>index.jsp</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">

    <script type="text/javascript"> function reloadCode(){ var time = new Date().getTime(); document.getElementById("imagecode").src="<%=request.getContextPath() %>/servlet/ImageServlet?d="+time; } </script>
  </head>

  <body>
    <form action="<%=request.getContextPath() %>/servlet/LoginServlet" method="get">
    验证码:<input type="text" name="checkcode"/>
    <img alt="验证码" id="imagecode" src="<%=request.getContextPath() %>/servlet/ImageServlet"/>
    <a href="javascript: reloadCode();">看不清楚,点击刷新</a><br>
    <input type="submit" value="提交">
    </form>
  </body>
</html>

ImageServlet.java 如下

package com.dulu;

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

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ImageServlet extends HttpServlet{
    public void  doGet(HttpServletRequest request,HttpServletResponse response)throws IOException{
         BufferedImage  bi = new BufferedImage(68,22,BufferedImage.TYPE_INT_RGB);
         Graphics g = bi.getGraphics();

         Random randrgb = new Random();
         //设置一个比较浅的背景色
         Color c = new Color(randrgb.nextInt(10)+235,randrgb.nextInt(10)+235,randrgb.nextInt(10)+235);
         g.setColor(c);         // 为g设置背景色
         g.fillRect(0,0,68,22); // 为g设置边框

         //画验证码中的内容
         //ch 得到含有字母和数字的数组
         char[] ch = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789".toCharArray();

         //随机获取数组中的4位
         Random r =new Random();
         int len = ch.length, index = 0;
         StringBuffer sb = new StringBuffer();
         for(int i=0;i<4;i++){
             index = r.nextInt(len);// index是数组中随机位置的索引 从0开始
             g.setColor(new Color(r.nextInt(88),r.nextInt(188),r.nextInt(255)));    
             g.drawString(ch[index]+"",(i*15)+ 3,18);//画出这个随机字符
             sb.append(ch[index]); // 将随机字符添加在sb尾部 
         }
         request.getSession().setAttribute("piccode",sb.toString());
            ImageIO.write(bi,"JPG",response.getOutputStream());


    }

}

LoginServlet.java 如下

package com.dulu;

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 {

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

        response.setContentType("text/html;charset=UTF-8");
        // piccode 是产生的随机验证码
        String piccode = (String) request.getSession().getAttribute("piccode");
        String checkcode = request.getParameter("checkcode");

        PrintWriter out = response.getWriter();

        if(checkcode!= ""){        //如果用户有输入的信息
            piccode = piccode.toUpperCase();     // 将系统产生的验证码字符大写
            checkcode = checkcode.toUpperCase(); // 将用户输入的字符大写
            // System.out.println("你输入的验证码是:"+ checkcode);
            if(checkcode.equals(piccode)){
                System.out.println("验证码输入正确!");
            }else{
                System.out.println("验证码输入错误!");
            }
        }else{   // 用户什么也没有输入
            System.out.println("你未输入验证码!");
        }   
        out.flush();// 刷新输出流
        out.close();// 关闭输出流
    }
}

web.xml 如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
  <servlet>
        <servlet-name>ImageServlet</servlet-name>
        <servlet-class>com.dulu.ImageServlet</servlet-class>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.dulu.LoginServlet</servlet-class>
  </servlet>

  <servlet-mapping>
         <servlet-name>ImageServlet</servlet-name>
         <url-pattern>/servlet/ImageServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/servlet/LoginServlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

测试如下:
输入正确的测试:

Java实现验证码

Java实现验证码

输入错误的测试
Java实现验证码

控制台输出:
你输入的验证码是:OPLK
验证码输入错误!

用户无输入,直接提交时:
控制台输出:你未输入验证码!