美文网首页
Java实现验证码功能

Java实现验证码功能

作者: 磊_5d71 | 来源:发表于2018-09-26 10:56 被阅读0次

字母数字混合验证码

  • CaptcahCode.java
package com.alan.code;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

        /**
         * 验证码工具类
         */
        public class CaptcahCode {

            /**
             * 验证码的生成方法
             * @param response
             * @return
             */
            public static String drawImage(HttpServletResponse response) {

                //1、使用stringbuilder类,对字符串进行处理。不用String,因为其赋值后不能改变。
                StringBuilder builder = new StringBuilder();
                //2、产生随机数,长度为4
                for (int i = 0; i < 4; i++) {
                    builder.append(randomChar());
                }

                String  code = builder.toString();
                //3、定义图片的宽度和高度,使用BufferedImage对象。
                int width = 120;
                int height = 25;

                BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
                //4、获取Graphics2D 绘制对象,开始绘制验证码
                Graphics2D g = bi.createGraphics();
                //5、定义文字的字体和大小
                Font font = new Font("微软雅黑",Font.PLAIN,20);
                //6、定义字体的颜色
                Color color = new Color(0,0,0);
                //设置字体
                g.setFont(font);
                //设置颜色
                g.setColor(color);
                //设置背景
                g.setBackground(new Color(226,226,240   ));
                //开始绘制对象
                g.clearRect(0,0,width,height);
                //绘制形状,获取矩形对象
                FontRenderContext context = g.getFontRenderContext();
                Rectangle2D bounds = font.getStringBounds(code,context);
                //计算文件的坐标和间距
                double x = (width - bounds.getWidth())/2;
                double y = (height- bounds.getHeight())/2;
                double ascent = bounds.getY();
                double baseY = y - ascent;
                g.drawString(code,(int)x,(int)baseY);
                //结束绘制
                g.dispose();

                try {
                    ImageIO.write(bi,"jpg",response.getOutputStream());
                    //刷新响应流
                    response.flushBuffer();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return code;

            }

            /**
             * 此方法用于用户产生随机字母和数字
             * @return
             */
            private static char randomChar(){
                // 1、定义验证需要的字母和数字
                String str = "ZXCVBNMASDFGHJKLQWERTYUIOP0123456789";
                //2、定义随机对象
                Random random = new Random();
                //3、返回随机字符
                return  str.charAt(random.nextInt(str.length()));

            }


        }
  • index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <img src="code.jsp" id="code">
    <a href="javascript:void(0);" onclick="changeCode()" >看不清,请点击</a>
    <script>
        function changeCode() {
            document.getElementById("code").src = "code.jsp?="+new Date().getTime();
        }

    </script>
  </body>
</html>
  • code.jsp
<%@ page import="com.alan.code.CaptcahCode" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    /**
     *     1、清空浏览器缓存。
     *     因为浏览器会对网站的资源文件和图像进行记忆存储,如果被浏览器加载过的图片就会记忆起来,记忆以后文件就不会和
     *     服务器交互,如果不清空的话可能会造成的问题是:验证刷新以后没有效果。
     */

    response.setHeader("pragma","no-cache");
    response.setHeader("cache-control","no-cache");
    response.setHeader("expires","0");

    //2、调用编写的生成验证码的工具,并将其存入session中

    String  code = CaptcahCode.drawImage(response);
    session.setAttribute("code",code);

    //3、解决getOutputStream() has already been called for this response异常
    out.clear();
    out = pageContext.pushBody();
%>

算术验证码

package com.alan.code;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

        /**
         * 验证码工具类
         */
        public class CaptcahCode {

            /**
             * 验证码的生成方法
             * @param response
             * @return
             */
            public static String drawImage(HttpServletResponse response) {

                //1、使用stringbuilder类,对字符串进行处理。不用String,因为其赋值后不能改变。
                StringBuilder builder = new StringBuilder();
                //2、产生随机数,长度为4
                for (int i = 0; i < 4; i++) {
                    builder.append(randomChar());
                }

                String  code = builder.toString();
                //3、定义图片的宽度和高度,使用BufferedImage对象。
                int width = 120;
                int height = 25;

                BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
                //4、获取Graphics2D 绘制对象,开始绘制验证码
                Graphics2D g = bi.createGraphics();
                //5、定义文字的字体和大小
                Font font = new Font("微软雅黑",Font.PLAIN,20);
                //6、定义字体的颜色
                Color color = new Color(0,0,0);
                //设置字体
                g.setFont(font);
                //设置颜色
                g.setColor(color);
                //设置背景
                g.setBackground(new Color(226,226,240   ));
                //开始绘制对象
                g.clearRect(0,0,width,height);
                //绘制形状,获取矩形对象
                FontRenderContext context = g.getFontRenderContext();
                Rectangle2D bounds = font.getStringBounds(code,context);
                //计算文件的坐标和间距
                double x = (width - bounds.getWidth())/2;
                double y = (height- bounds.getHeight())/2;
                double ascent = bounds.getY();
                double baseY = y - ascent;
                g.drawString(code,(int)x,(int)baseY);
                //结束绘制
                g.dispose();

                try {
                    ImageIO.write(bi,"jpg",response.getOutputStream());
                    //刷新响应流
                    response.flushBuffer();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return code;

            }

            /**
             * 算术表达式验证码
             *
             * 1、干扰线的产生
             * 2、范围随机颜色、随机数
             * @param response
             * @return
             */
            public static String drawImageVerificate(HttpServletResponse response){

                //定义验证码的宽度和高度
                int width = 100, height = 30;
                //在内存中创建图片
                BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
                //创建图片上下文
                Graphics2D g = image.createGraphics();
                //产生随机对象,用于算术表达式的数字
                Random random = new Random();
                //设置背景
                g.setColor(getRandomColor(240,250));
                //设置字体
                g.setFont(new Font("微软雅黑",Font.PLAIN,22));
                //开始绘制
                g.fillRect(0,0,width,height);

                //干扰线的绘制,绘制线条到图片中
                g.setColor(getRandomColor(180,230));
                for (int i = 0; i < 100; i++) {
                    int x = random.nextInt(width);
                    int y = random.nextInt(height);
                    int x1 = random.nextInt(60);
                    int y1 = random.nextInt(60);
                    g.drawLine(x,y,x1,y1);
                }

                //对算术验证码表达式的拼接
                int num1 = (int) (Math.random()*10+1);
                int num2 = (int) (Math.random()*10+1);
                int operator = random.nextInt(3);
                String operatorStr = null;
                int result = 0;
                switch (operator) {
                    case 0:
                        operatorStr = "+";
                        result = num1+num2;
                        break;
                    case 1:
                        operatorStr = "-";
                        result = num1-num2;
                        break;
                    case 2:
                        operatorStr = "*";
                        result = num1*num2;
                        break;

                }

                //图片显示的算术文字
                String calc = num1 + " "+ operatorStr +" "+num2+" = ?";
                //设置随机颜色
                g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
                //绘制表达式
                g.drawString(calc,5,25);
                //结束绘制
                g.dispose();

                //输出图片到页面
                try {
                    ImageIO.write(image,"JPEG",response.getOutputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return  String.valueOf(result);
            }

            /**
             * 随机颜色生成
             * @param fc
             * @param bc
             * @return
             */
            public static Color getRandomColor(int fc,int bc){
                //利用随机数
                Random random = new Random();
                if(fc>255){
                    fc = 255;
                }
                if(bc>255){
                    bc = 255;
                }
                int r = fc+random.nextInt(bc-fc);
                int g = fc+random.nextInt(bc-fc);
                int b = fc+random.nextInt(bc-fc);

                return  new Color(r,g,b);

            }

            /**
             * 此方法用于用户产生随机字母和数字
             * @return
             */
            private static char randomChar(){
                // 1、定义验证需要的字母和数字
                String str = "ZXCVBNMASDFGHJKLQWERTYUIOP0123456789";
                //2、定义随机对象
                Random random = new Random();
                //3、返回随机字符
                return  str.charAt(random.nextInt(str.length()));

            }


        }

使用kcaptcha框架实现验证码功能

  • test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>关于验证码框架之--Kaptcha</title>
</head>
<style>
    #code{
        height: 30px;
    }

</style>
<body>
<form action="submit.action">
    <p>验证码:<input type="text" name="kaptcha" id="code" maxlength="4" value="" /><img src="http://localhost:8080/kaptcha.jpg" id="changeCode"/></p>
    <!--使用ajax方式,type定义为button类型,而不是submit类型-->
    <p><input type="button" value="登陆" id="login"></p>
    <div id="result"></div>
</form>
<script src="js/jquery-1.12.4.min.js"></script>
    <script>
        $(function () {
            $("#changeCode").click(function () {
                $(this).attr("src","http://localhost:8080/kaptcha.jpg?="+new Date().getTime());
            });

            //给登陆按钮绑定点击事件
            $("#login").click(function () {

                //获取用户输入的验证码
                var code = $("#code").val();
                var params = {"code":code};
                $.post("http://localhost:8080/login",params,function (data) {
                    //alert(data);
                    if(data == "success"){
                        $("#result").html("验证码输入正确");
                    }else{
                        $("#result").html("验证码输入有误,请重新输入...");
                        //重新聚焦到input标签
                        $("#code").val("").focus();
                    }
                });
            });
        });

    </script>
</body>
</html>
  • LoginServlet
package com.alan.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //设置编码
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        //获取浏览器输出流对象
        PrintWriter out = response.getWriter();
        //获取用户传递过来的验证码
        String code = request.getParameter("code");
        //获取验证码框架产生的验证码,框架会把验证码以常量的方式放在session中
        String sessionCode = (String) request.getSession().getAttribute("kcode");

        System.out.println(code+"===="+sessionCode);
        if(code!=null&&sessionCode!=null){
            //用户输入的验证码和服务端生成的验证码一致时,返回success
            if(code.equalsIgnoreCase(sessionCode)){
                out.print("success");
            }else {
                out.print("fail");
            }
        }else {
            out.print("fail");
        }
        out.flush();
        out.close();

    }

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

        this.doPost(request,response);
    }
}
  • web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 关于kaptcha验证码-->
    <servlet>
        <servlet-name>Kaptcha</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
        <init-param>
            <param-name>kaptcha.image.width</param-name>
            <param-value>200</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.image.height</param-name>
            <param-value>50</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.char.length</param-name>
            <param-value>4</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.noise.impl</param-name>
            <param-value>com.google.code.kaptcha.impl.NoNoise</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.obscurificator.impl</param-name>
            <param-value>com.google.code.kaptcha.impl.FishEyeGimpy</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.session.key</param-name>
            <param-value>kcode</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Kaptcha</servlet-name>
        <url-pattern>/kaptcha.jpg</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.alan.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
</web-app>

相关文章

  • Java生成验证码简记

    Java生成验证码简记 $.ajax和java后台实现用户登录的功能 注意:在ImageServlet中最后一行...

  • 2018-10-30

    实现验证码功能

  • 2018-10-26

    实现验证码功能

  • Java实现字符验证码、运算验证码

    Java中很轻松可以实现验证码功能,在原生AWT图形化工具包中写一点简单的逻辑就能轻松完成验证码功能。本文,同时将...

  • Java实现验证码功能

    字母数字混合验证码 CaptcahCode.java index.jsp code.jsp 算术验证码 使用kca...

  • 短信API实现自动化短信发送

    短信验证码接口示例,如何接入短信API接口实现短信自动发送功能; 网站如何实现自动发送短信验证码的功能,短信验证码...

  • 接入短信API,免费试用

    短信验证码接口示例,如何接入短信API接口实现短信自动发送功能; 网站如何实现自动发送短信验证码的功能,短信验证码...

  • Java生成图片验证码

    Java生成图片验证码 手动实现图片验证码生成 调用演示

  • Java实现验证码制作

    Java实现验证码制作 第一章 概述 1.1 验证码概述 为什么要使用验证码什么是验证码使用Servlet实现验证...

  • java实习面试题

    1.佰益源公司 (1)自我介绍 (2)项目介绍,各种功能的展示与实现 (3)验证码的实现 (4)java的几种数据...

网友评论

      本文标题:Java实现验证码功能

      本文链接:https://www.haomeiwen.com/subject/xtlkoftx.html