Java 图片验证码/图形验证码 亲测

1. Maven包 pom.xml

  <!-- 父级 pom.xml-->
  <properties>
    <spring-boot.version>1.5.17.RELEASE</spring-boot.version>
  </properties>
  
  <dependencyManagement>
    <dependencies>
      <!--Spring IO 控制依赖版本适配-->
      <dependency>
        <groupId>io.spring.platform</groupId>
        <artifactId>platform-bom</artifactId>
        <version>Brussels-SR14</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--Spring Boot 控制依赖版本适配-->
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
           <groupId>net.sourceforge.nekohtml</groupId>
           <artifactId>nekohtml</artifactId>
           <version>1.9.22</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.social</groupId>
           <artifactId>spring-social-config</artifactId>
           <version>1.1.6.RELEASE</version>
       </dependency>
    </dependencies>
   </dependencyManagement>

    <!-- 子级 pom.xml-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-config</artifactId>
        </dependency>
    </dependencies>

2. 图片验证码工具类


import lombok.Data;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.time.LocalDateTime;
import java.util.Random;

@Data
public class ImageVerify {
    @Data
    public static class ImageCode {
        private BufferedImage image;
        private String code;
        private LocalDateTime expireTime;

        public ImageCode(final BufferedImage image, final String code, final int expireIn) {
            this.image = image;
            this.code = code;
            this.expireTime = LocalDateTime.now().plusSeconds(expireIn);
        }

        public boolean isExpire() {
            return LocalDateTime.now().isAfter(expireTime);
        }
    }

    private int width = 100;                  // 验证码图片宽度
    private int height = 36;                  // 验证码图片长度
    private int length = 4;                   // 验证码位数
    private int fontSize = 32;                // 验证码字体大小
    private int letterSpace = fontSize / 2;   // 字母间隔
    private int lineSize = 200;               // 干扰线数量
    private int expireIn = 60;                // 验证码有效时间 60s
    private int positionX = 18;               // x轴距
    private int positionY = 28;               // y轴距

    public ImageVerify() {}

    public ImageVerify(final int expireIn) {
        this.expireIn = expireIn;
    }

    public ImageVerify(final int width, final int height, final int length, final int fontSize, final int expireIn, final int positionX, final int positionY) {
        this.width = width;
        this.height = height;
        this.length = length;
        this.fontSize = fontSize;
        this.expireIn = expireIn;
        this.positionX = positionX;
        this.positionY = positionY;
    }

    public ImageCode create() {
        final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        final Graphics graphics = image.getGraphics();
        graphics.setColor(getRandColor(200, 500));
        graphics.fillRect(0, 0, width, height);
        graphics.setFont(new Font("Times New Roman", Font.ITALIC, fontSize));
        graphics.setColor(getRandColor(100, 200));

        final Random random = new Random();

        /** 画干扰线*/
        for (int i = 0; i < lineSize; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            graphics.drawLine(x, y, x + xl, y + yl);
        }

        /** 画验证码*/
        final StringBuilder sRand = new StringBuilder();
        for (int i = 0; i < length; i++) {
            final String rand = String.valueOf(random.nextInt(10));
            sRand.append(rand);
            graphics.setColor(
                    new Color(
                            20 + random.nextInt(110),
                            20 + random.nextInt(110),
                            20 + random.nextInt(110)
                    )
            );
            graphics.drawString(rand, letterSpace * i + positionX, positionY);
        }
        graphics.dispose();

        return new ImageCode(image, sRand.toString(), expireIn);
    }

    private Color getRandColor(int fc, int bc) {
        final Random random = new Random();
        if (fc > 255) fc = 255;
        if (bc > 255) bc = 255;
        final int r = fc + random.nextInt(bc - fc);
        final int g = fc + random.nextInt(bc - fc);
        final int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

}

3. 生成验证码,图片验证码 和 验证接口


import lombok.Data;

@Data
public class TestVo {
    private String code;
}

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
public class ImageVerifyController {
    /**
     * Session Key
     * */
    public final static String SESSION_KEY_IMAGE_CODE = "SESSION_KEY_IMAGE_CODE";

    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

   	/**
	* 生成图片验证码接口
	*/
    @GetMapping("/imageVerify")
    public void imageVerify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        final ImageVerify.ImageCode imageCode = new ImageVerify(
                68,/** 验证码图片宽度*/
                36,/** 验证码图片长度*/
                4,/** 验证码位数*/
                32,/** 验证码字体大小*/
                60,/** 验证码有效时间(秒)*/
                2,/** x轴距*/
                28/** y轴距*/
        ).create();

        sessionStrategy.setAttribute(
                new ServletWebRequest(request),
                SESSION_KEY_IMAGE_CODE,
                imageCode
        );

        ImageIO.write(imageCode.getImage(), "jpeg", response.getOutputStream());
        response.getOutputStream().flush();
    }

   	/**
	* 验证接口
	*/
    @PostMapping("/verify")
    public Map<String, String> verify(TestVo testVo, ServletWebRequest servletWebRequest) {
        final ImageVerify.ImageCode imageCode = (ImageVerify.ImageCode) sessionStrategy.getAttribute(servletWebRequest, SESSION_KEY_IMAGE_CODE);

        Map<String, String> m = new HashMap<>();

        if (StringUtils.isBlank(testVo.getCode())) {
            m.put("message", "验证码不能为空!");
            return m;
        }

        if (imageCode == null) {
            m.put("message", "验证码不存在!");
            return m;
        }

        if (imageCode.isExpire()) {
            sessionStrategy.removeAttribute(servletWebRequest, SESSION_KEY_IMAGE_CODE);
            m.put("message", "验证码已过期!");
            return m;
        }

        if (!StringUtils.equalsIgnoreCase(imageCode.getCode(), testVo.getCode())) {
            m.put("message", "验证码不正确!");
            return m;
        }

        sessionStrategy.removeAttribute(servletWebRequest, SESSION_KEY_IMAGE_CODE);

        m.put("message", "成功");
        return m;
    }

   	/**
	* 验证页面
	*/
    @GetMapping("/index")
    public String index() {
        return "index";
    }
    
}

  • 生成图片验证码
    在这里插入图片描述

4. 验证页面 index.html


<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript"src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<h2>Hello World!</h2>

<span>
    <input type="text" id="textCode" placeholder="验证码" style="width: 50px" maxlength="4"/>
    <img id="imageCode" src="/imageVerify" onclick="$(this).prop('src', '/imageVerify?' + Math.random())"/>
    <input type="button" value="确认" onclick="verify()"/>
</span>

<script>
    function verify() {
        $.ajax({
            async: false,
            type: 'post',
            url: '/verify',
            dataType: "json",
            data: {
                code: $('#textCode').val()
            },
            success: function (result) {
                if (result) {
                    console.log(result.message);
                } else {
                    alert("failed!");
                }
                $("#imageCode").prop("src", '/imageVerify?' + Math.random());
            }
        });
    }
</script>
</body>
</html>

在这里插入图片描述

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值