spring框架下的ajax生成验证码以及进行验证码验证

本文介绍如何在Spring框架下结合Ajax实现验证码的生成与验证。通过创建VerifyCodeController控制类,设置初始化图片和响应前端请求的方法,配合前端页面使用ajax进行交互,完成动态验证码的展示与验证功能。配置包括web.xml和springmvc.xml文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、大概思路

  1. 创建验证码控制类VerifyCodeController,控制类下有初始化图片的方法和响应前端请求的方法
  2. 编写前端页面
  3. 利用ajax连接前端和后台,进行图片的动态生成和验证

实际效果图:

这里写图片描述

具体实现

1.验证码控制类VerifyCodeController

package com.bill.controller;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * @author zkc
 */
@Controller
@RequestMapping("verify")
public class VerifyCodeController {
    // 验证码图片的宽度。
    private int width = 60;
    // 验证码图片的高度。
    private int height = 20;
    // 验证码字符个数
    private int codeCount = 4;
    private int x = 0;
    // 字体高度
    private int fontHeight;
    private int codeY;
    //验证码图片上会出现的字母和数字
    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' };
    /**
     * 初始化验证图片属性
     */
    public void init() throws ServletException {
        // 从web.xml中获取初始信息
        // 宽度
        String strWidth ="80";
        // 高度
        String strHeight ="30";
        // 字符个数
        String strCodeCount = "4";
        // 将配置的信息转换成数值
        try {
            if (strWidth != null && strWidth.length() != 0) {
                width = Integer.parseInt(strWidth);
            }
            if (strHeight != null && strHeight.length() != 0) {
                height = Integer.parseInt(strHeight);
            }
            if (strCodeCount != null && strCodeCount.length() != 0) {
                codeCount = Integer.parseInt(strCodeCount);
            }
        } catch (NumberFormatException e) {
        }
        x = width / (codeCount + 1);
        fontHeight = height - 2;
        codeY = height - 4;
    }

    @RequestMapping(value="/code.action",method= RequestMethod.GET)
    public void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, java.io.IOException {
        init();
        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffImg.createGraphics();
        // 创建一个随机数生成器类
        Random random = new Random();
        // 将图像填充为白色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);
        // 创建字体,字体的大小应该根据图片的高度来定。
        Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
        // 设置字体。
        g.setFont(font);
        // 画边框。
        g.setColor(Color.BLACK);
        g.drawRect(0, 0, width - 1, height - 1);
        // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。
        g.setColor(Color.BLACK);
        for (int i = 0; i < 10; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.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 strRand = String.valueOf(codeSequence[random.nextInt(36)]);
            // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
            // 用随机产生的颜色将验证码绘制到图像中。
            g.setColor(new Color(red, green, blue));
            g.drawString(strRand, (i + 1) * x, codeY);
            // 将产生的四个随机数组合在一起。
            randomCode.append(strRand);
        }
        // 将四位数字的验证码保存到Session中。
        HttpSession session = req.getSession();
        session.setAttribute("validateCode", randomCode.toString());
        // 禁止图像缓存。
        resp.setHeader("Pragma", "no-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);
        resp.setContentType("image/jpeg");
        // 将图像输出到Servlet输出流中。
        ServletOutputStream sos = resp.getOutputStream();
        ImageIO.write(buffImg, "jpeg", sos);
        sos.close();
    }
    //响应前端请求的方法
    @RequestMapping(value="/checkVerifyCode.action",method= RequestMethod.POST)
    @ResponseBody
    public Object checkVerifyCode(@RequestParam(value = "verifyCode") String verifyCode,HttpServletRequest req, HttpServletResponse resp){
      JSONObject jsobjcet = new JSONObject();
      String flag = null;
      if(verifyCode!=null){
          HttpSession session = req.getSession();
          //获取图片中的验证码
          String validateCode= (String) session.getAttribute("validateCode");
          //输入的与图片中的进行比较
          if(validateCode!=null&&validateCode.equals(verifyCode.toUpperCase())){
              jsobjcet.put("valid", true);
              flag = "true";
          }else{
              jsobjcet.put("valid", false);
              flag = "false";
          }
      }else{
          jsobjcet.put("valid", false);
          flag = "false";
      }
      return flag;
    }
}

2.前端页面代码(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>My JSP 'index.jsp' starting page</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" src="js/jquery-1.11.0.js"></script>
    <script type="text/javascript">
        $(function(){
            $("form").submit(function(e){
                if($("#tel").val()==""){
                    alert("手机号不能为空");
                    e.preventDefault();
                }else if($("#pwd").val()==""){
                    alert("密码不能为空");
                    e.preventDefault();
                }else if($("input[name=validateCode]").val()==""){
                    alert("验证码不能为空");
                    e.preventDefault();
                }else{
                    <!-- 获取输入的验证码 -->
                    var verifyCode=$("input[name=validateCode]").val();
                    <!-- 通过ajax方式将值传到后台 -->
                    $.ajax({
                        url:"verify/checkVerifyCode.action",<!-- 要传的地址 -->
                        type:"post",                        <!-- 传值的方式 -->
                        data:{"verifyCode":verifyCode},     <!-- 传的数据(json对象) -->
                        async:false,                        <!-- 是否异步 -->
                        success:function(result){           <!-- 成功后执行的代码 -->
                            if(result=="false"){
                                alert("验证码错误");
                                e.preventDefault();
                            }else{
                                $("form").submit();
                            }

                        }
                    });
                }
            });
            <!-- 刷新图片 -->
            $("#refresh").unbind("click").bind("click",function(){
                <!-- 传递一个随机数给后台 -->
                $("#verify").attr("src","verify/code.action?r"+Math.random());
            });
        });
    </script>
  </head>

  <body>
        <form action="login.action" method="post">
            <table>
                <tr>
                    <td>手机号码:</td>
                    <td><input type="text" name="tel" id="tel"/></td>
                </tr>
                <tr>
                    <td>服务密码:</td>
                    <td><input type="password" name="pwd" id="pwd"/></td>
                </tr>
                <tr>
                    <!-- 验证码 -->
                    <td>验证码:</td>
                    <td><input type="text" name="validateCode" id="code"/></td>
                    <td>
                        <!-- 验证码图片 -->
                        <img src="verify/code.action" id="verify"/>
                        <!-- 点击更换验证码图片 -->
                        <a id="refresh">看不清?</a>
                    </td>
                </tr>
            </table>
            <input type="submit" value="登录"/>
        </form>
  </body>
</html>

由于我用了spring框架,所以还需要配置一下xml文件,下面是配置信息
这里写图片描述

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" 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>billplatform</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <!-- Spring  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-mybatis.xml</param-value>
  </context-param>
  <!-- Spring监听 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- Spring MVC -->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>*.action</url-pattern>           <!-- 拦截所有.action请求 -->
  </servlet-mapping>

  <!-- 过滤器统一字符  -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>

2.springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
 xmlns:context="http://www.springframework.org/schema/context"  
 xmlns:p="http://www.springframework.org/schema/p"  
 xmlns:mvc="http://www.springframework.org/schema/mvc"  
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
      http://www.springframework.org/schema/context  
      http://www.springframework.org/schema/context/spring-context.xsd  
      http://www.springframework.org/schema/mvc  
      http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

      <!-- 注解扫描(扫描所有包下)-->
      <context:component-scan base-package="com.bill.*"></context:component-scan>

      <!-- 配置视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--  配置视图的前缀 
            <property name="prefix" value=""></property>-->
            <!--  配置视图的后缀
            <property name="suffix" value=".jsp"></property> -->
        </bean>
</beans>

以上就是我在spring框架下用ajax实现的一个简单的验证码功能,第一次写博客,很多地方不足,欢迎大家能指出,谢谢。

采用ajax技术实现的图形验证码,在前端进行验证验证码信息为图片。每一行代码均有注释,通俗易懂。 实现步骤: 1、创建web工程 2、在jsp页面,编写一个 3、编写一个servlet,在servlet中产生图形验证码 ------------------------------------------------------------ //1、给客户端作出的回应是以图片的方式来回应 response.setContentType("image/jpeg"); //2、创建一个图形缓冲区,用于绘制图形 (宽度,高度,颜色的生成方案) BufferedImage image = new BufferedImage(800,600,BufferedImage.TYPE_INT_RGB); //3、创建一支画笔(图形设备接口)用于绘图 Graphics g = image.getGraphics(); //4、指定图笔的颜色 g.setColor(getColor(200,256)); //5、绘制一个矩形框,作为验证码的背景 g.fillRect(0,0, 800,600); //产生一个输出流,准备把图片以流的方式,输出到客户端 OutputStream out = response.getOutputStream(); //输出在图形缓冲区中,绘制的图片 ImageIO.write(image,"jpg",out); //关闭流 out.close(); //随机生成背景颜色 private Random rd = new Random(); //产生随机数类 public Color getColor(int start,int end){ int r = start+rd.nextInt(end-start); int g = start+rd.nextInt(end-start); int b = start+rd.nextInt(end-start); return new Color(r, g, b);//根据三原色的值,随机在指定范围内,生成一种颜色 } --------------------------------------------------------------------------- 0-120 比较适合文字的颜色 100-200 适合干扰线条的颜色 200-255 适合背景颜色 --------------------------------------------------------------------------- 生成图片中的文字: 1、先编写一个字符串,包含:数字,大小字母 private String s = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 2、在产生背景之后,编写如下代码,产生四个字符(并且,把生成字符,保存在session中,在登录的时候用来做判断) String code=""; //用于保存生成的四个字符 for(int i=0;i<4;i++){ //生成一个随机数,它的取值范围,一定要在s这个字符串的长度范围之内 int index = rd.nextInt(s.length()); //2 //把index作为下标,来取得字符串的中某一个字符 char c = s.charAt(index); //指定文字的颜色----深色段 g.setColor(getColor(0,120)); //创建一个字体 Font f = new Font("隶书",Font.ITALIC|Font.BOLD,60+rd.nextInt(60)); //把字体关联到画笔 g.setFont(f); code+=c; //把生成的字符连接成一个字符串 //把文字输出到图片上 g.drawString(String.valueOf(c), 100+i*80+rd.nextInt(100),200+rd.nextInt(150)); } request.getSession().setAttribute("code",code);//把生成验证码信息,存储到session中,登录的时候,用来作判断 ------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值