图形验证码实现方案(解决短信轰炸问题)

       最近收到leader的一个邮件说我们的项目有短信轰炸风险。顿时让一个做技术开发的人为之一颤。今天给大家介绍一个解决这个问题的使用工具。

就是谷歌的 kaptcha 进行验证码生成和校验。闲话少说直接上代码。

1. 首先下载一个工具包

<dependency>
    <groupId>com.github.axet</groupId>
    <artifactId>kaptcha</artifactId>
    <version>0.0.9</version>
</dependency>

2. 建立一个spring工程填写相关代码。 两个方法一个是获取图形验证码 一个是用于验证。

@Controller
@RequestMapping("/kaptcha")
public class kaptchaController {
    @Autowired
    private Producer captchaProducer = null;

    @RequestMapping("/getKaptchaImage")
    public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        String code = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        System.out.println("******************验证码是: " + code + "******************");

        response.setDateHeader("Expires", 0);

        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");

        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");

        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");

        // return a jpeg
        response.setContentType("image/jpeg");

        // create the text for the image
        String capText = captchaProducer.createText();

        // store the text in the session
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);

        // create the image with the text
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();

        // write the data out
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
        return null;
    }
    @RequestMapping("/check")
    public String check(HttpServletRequest request){
        //从session中取出servlet生成的验证码text值
        String kaptchaExpected = (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        //获取用户页面输入的验证码
        String kaptchaReceived = request.getParameter("kaptcha");
        //校验验证码是否正确
        if (kaptchaReceived == null || !kaptchaReceived.equalsIgnoreCase(kaptchaExpected)){
            return "false";
        }
        return "true";
    }
    @RequestMapping("/index")
    public String index(HttpServletRequest request){
        return "kaptcha";
    }

}

3. springmvc.xml中加上配置。

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

    <!--指明 controller 所在包,并扫描其中的注解-->
    <context:component-scan base-package="com.mzq" />
    <!-- 静态资源(js、image等)的访问 -->
    <mvc:default-servlet-handler/>

    <!-- 通过annotation-driven可以替代下边的处理器映射器和适配器 -->
    <mvc:annotation-driven />
    <!--静态资源解析 -->
    <mvc:resources mapping="/js/**" location="/WEB-INF/js/" />
    <mvc:resources mapping="/css/**" location="/WEB-INF/css/" />
    <mvc:resources mapping="/img/**" location="/WEB-INF/img/" />



    <!--ViewResolver 视图解析器-->
    <!--用于支持Servlet、JSP视图解析-->
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 定义统一异常处理器 -->
    <bean class="com.mzq.exception.MyExceptionResolver"></bean>
    
<!-- 
kaptcha.border.color   边框颜色   默认为Color.BLACK  
kaptcha.border.thickness  边框粗细度  默认为1  
kaptcha.producer.impl   验证码生成器  默认为DefaultKaptcha  
kaptcha.textproducer.impl   验证码文本生成器  默认为DefaultTextCreator  
kaptcha.textproducer.char.string   验证码文本字符内容范围  默认为abcde2345678gfynmnpwx  
kaptcha.textproducer.char.length   验证码文本字符长度  默认为5  
kaptcha.textproducer.font.names    验证码文本字体样式  默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)  
kaptcha.textproducer.font.size   验证码文本字符大小  默认为40  
kaptcha.textproducer.font.color  验证码文本字符颜色  默认为Color.BLACK  
kaptcha.textproducer.char.space  验证码文本字符间距  默认为2  
kaptcha.noise.impl    验证码噪点生成对象  默认为DefaultNoise  
kaptcha.noise.color   验证码噪点颜色   默认为Color.BLACK  
kaptcha.obscurificator.impl   验证码样式引擎  默认为WaterRipple  
kaptcha.word.impl   验证码文本字符渲染   默认为DefaultWordRenderer  
kaptcha.background.impl   验证码背景生成器   默认为DefaultBackground  
kaptcha.background.clear.from   验证码背景颜色渐进   默认为Color.LIGHT_GRAY  
kaptcha.background.clear.to   验证码背景颜色渐进   默认为Color.WHITE  
kaptcha.image.width   验证码图片宽度  默认为200  
kaptcha.image.height  验证码图片高度  默认为50   
 -->
    <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">  
        <property name="config">  
            <bean class="com.google.code.kaptcha.util.Config">  
                <constructor-arg>  
                    <props>
                        <prop key="kaptcha.border">no</prop>
                        <prop key="kaptcha.border.color">105,179,90</prop>
                        <prop key="kaptcha.textproducer.font.color">black</prop>
                        <prop key="kaptcha.image.width">100</prop>
                        <prop key="kaptcha.image.height">40</prop>
                        <prop key="kaptcha.textproducer.font.size">30</prop>
                        <prop key="kaptcha.session.key">code</prop>
                        <prop key="kaptcha.textproducer.char.length">4</prop>
                        <prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
                    </props>
                </constructor-arg>  
            </bean>  
        </property>
        </bean>

</beans>

4. 写一个JSP页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    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" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<script type="text/javascript" src="../js/jquery-1.11.0.min.js"></script>  
<!-- <script type="text/javascript" src="../js/functions.js"></script>   -->
  
  
<title>测试页面</title>  
<script type="text/javascript">  
$(function(){         
    $('#kaptchaImage').click(function () {//生成验证码  
     $(this).hide().attr('src', '../kaptcha/getKaptchaImage?' + Math.floor(Math.random()*100) ).fadeIn();  
     event.cancelBubble=true;  
    });  
});   
  
  
window.onbeforeunload = function(){  
    //关闭窗口时自动退出  
    if(event.clientX>360&&event.clientY<0||event.altKey){     
        alert(parent.document.location);  
    }  
};  
  
  
function changeCode() {  
    $('#kaptchaImage').hide().attr('src', '../kaptcha/getKaptchaImage?' + Math.floor(Math.random()*100) ).fadeIn();  
    event.cancelBubble=true;  
}  
</script>  
</head>  
<body>  
          
<div class="chknumber">
      <form action="../kaptcha/check">
      <label>验证码:  
      <input name="kaptcha" type="text" id="kaptcha" maxlength="4" class="chknumber_input" />
            </label>
            <br />
      <img src="../kaptcha/getKaptchaImage" id="kaptchaImage"  style="margin-bottom: -3px"/>  
      <a href="#" onclick="changeCode()">看不清?换一张</a>
      <input type="submit" value="提交">
      </form>

</div>  
</body>  
</html>  

 5. web.xml中别忘了加载这个springmvc.xml文件

  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>mvc-dispatcher</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>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
  </servlet>
  <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 配置SESSION超时,单位是分钟 -->
  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>
<!-- Spring和mybatis的配置文件 -->
  <filter>
    <filter-name>encodingFilter</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>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!-- 防止Spring内存溢出监听器 -->
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  </listener>

6. 启动项目后和效果如下。

7. 项目源码希望大家来探讨。

https://github.com/owenma/kaptcha_demo

如果觉得有疑问或者对你有帮助 欢迎评论。

作者:森林木马

  如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意 

转载文章之后必须在 文章页面明显位置给出作者和原文连接否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/owenma/p/7375540.html