关于springboot:Trainee0722第一个任务使用jar包captcha实现验证码

6次阅读

共计 8151 个字符,预计需要花费 21 分钟才能阅读完成。

尽管老大说这是一个特简略的小我的项目,然而我这个没有接触过 springboot 的人感觉难的批爆,最终历时四个小时才做进去。

需要

实现一个小东西,用 captcha jar 包做一个 demo,实现登陆的验证码,用以验证一下 captcha 的设置问题。

难点

  • 在校期间只是做一些算法方面的问题,没有接触过框架常识。
  • 始终用的是 Eclipse,当初要改用 IDEA。

Step1:入手

创立 Spring Boot 我的项目

创立 Spring Boot 我的项目有三种办法,见【尚硅谷 Spring Boot】入门 5 ~ 8:HelloWorld,应用 IDEA,中的 Spring Initializr 间接创立 Spring Boot 我的项目最为不便。

关上 IDEA,点击 Create New Project ➡ Spring Initializr,如图所示:

在这里抉择好 JDK 版本。


这一步要留神 Java Version 的抉择。

按需抉择,这里我创立 Spring Web 我的项目:

这一步留神 Spring Boot 版本的抉择。

这里在界面左上角能够搜寻并增加须要增加的依赖(Dependencies)如 Lombok、Thymeleaf 等,当然依赖也能够在生成我的项目之后在 pom.xml 文件中手动增加。


给我的项目取个名字吧!

创立胜利后这些文件能够删除:

胜利:

导入 kaptcha 依赖

在 pom.xml 文件中增加:

<!-- Kaptcha -->
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

Step2:剖析

有两种形式在 Spring Boot 中应用 kaptcha:

  1. 应用.xml 的配置形式配置生成 kaptcha 的 bean 对象,在启动类上应用 @ImportResource 引入这个 xml 文件,在 controller 中注入其对象并应用;
  2. 把 kaptcha 作为工程的一个类,加上 @Configuration 注解,在返回 kaptcha 的办法中加上 @Bean 注解,再在 controller 中注入其对象。

Step3.1:办法 1

①创立 KaptchaConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd">
    <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
        <property name="config">
            <bean class="com.google.code.kaptcha.util.Config">
                <constructor-arg type="java.util.Properties">
                    <props>
                        <!-- 是否应用边框 -->
                        <prop key = "kaptcha.border">yes</prop>
                        <!-- 边框色彩 -->
                        <prop key="kaptcha.border.color">105,179,90</prop>
                        <!-- 验证码字体色彩 -->
                        <prop key="kaptcha.textproducer.font.color">blue</prop>
                        <!-- 验证码图片的宽度 -->
                        <prop key="kaptcha.image.width">100</prop>
                        <!-- 验证码图片的高度 -->
                        <prop key="kaptcha.image.height">50</prop>
                        <!-- 验证码字体的大小 -->
                        <prop key="kaptcha.textproducer.font.size">27</prop>
                        <!-- 验证码保留在 session 的 key-->
                        <prop key="kaptcha.session.key">code</prop>
                        <!-- 验证码输入的字符长度 -->
                        <prop key="kaptcha.textproducer.char.length">4</prop>
                        <!-- 验证码的字体设置 -->
                        <prop key="kaptcha.textproducer.font.names"> 宋体, 楷体, 微软雅黑 </prop>
                        <!-- 验证码的取值范畴 -->
                        <prop key="kaptcha.textproducer.char.string">0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ</prop>
                        <!-- 图片的款式 -->
                        <prop key="kaptcha.obscurificator.impl">com.google.code.kaptcha.impl.WaterRipple</prop>
                        <!-- 烦扰色彩,非法值:r,g,b 或者 white,black,blue.-->
                        <prop key="kaptcha.noise.color">black</prop>
                        <!-- 烦扰实现类 -->
                        <prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.DefaultNoise</prop>
                        <!-- 背景色彩突变,开始色彩 -->
                        <prop key="kaptcha.background.clear.from">185,56,213</prop>
                        <!-- 背景色彩突变,完结色彩 -->
                        <prop key="kaptcha.background.clear.to">white</prop>
                        <!-- 文字距离 -->
                        <prop key="kaptcha.textproducer.char.space">3</prop>
                    </props>
                </constructor-arg>
            </bean>
        </property>
    </bean>
</beans>

②在启动类上引入这个文件

@SpringBootApplication
@ImportResource(locations={"classpath:KaptchaConfig.xml"})

public class CaptchaApplication {public static void main(String[] args) {
        // SpringApplication
        SpringApplication.run(CaptchaApplication.class, args);
    }
}

③编写 Controller

@RestController
public class KaptchaController {

    // 在 Controller 中注入 defaultKaptcha
    @Autowired
    DefaultKaptcha defaultKaptcha;

    // 获取验证码
    @RequestMapping("/getKaptcha")
    public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {byte[] captchaChallengeAsJpeg = null;
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        try {
            // 生产验证码字符串并保留到 session 中
            String createText = defaultKaptcha.createText();
            httpServletRequest.getSession().setAttribute("verifyCode", createText);
            // 应用生产的验证码字符串返回一个 BufferedImage 对象并转为 byte 写入到 byte 数组中
            BufferedImage challenge = defaultKaptcha.createImage(createText);
            ImageIO.write(challenge, "jpg", jpegOutputStream);
        } catch (IllegalArgumentException e) {httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        // 定义 response 输入类型为 image/jpeg 类型,应用 response 输入流输入图片的 byte 数组
        captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
        httpServletResponse.setHeader("Cache-Control", "no-store");
        httpServletResponse.setHeader("Pragma", "no-cache");
        httpServletResponse.setDateHeader("Expires", 0);
        httpServletResponse.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream =
                httpServletResponse.getOutputStream();
        responseOutputStream.write(captchaChallengeAsJpeg);
        responseOutputStream.flush();
        responseOutputStream.close();}
}

Step3.2:办法 2

①创立 KaptchaConfig 配置类

应用 @Component 注解使其作为配置类。

@Component
public class KaptchaConfig {@Bean("captchaProducer")
    public DefaultKaptcha getDefaultKaptcha(){com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
        Properties properties = new Properties();
        // 图片边框
        properties.setProperty("kaptcha.border", "yes");
        // 边框色彩
        properties.setProperty("kaptcha.border.color", "105,179,90");
        // 字体色彩
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        // 图片宽
        properties.setProperty("kaptcha.image.width", "110");
        // 图片高
        properties.setProperty("kaptcha.image.height", "40");
        // 字体大小
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        // session key
        properties.setProperty("kaptcha.session.key", "code");
        // 验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        // 字体
        properties.setProperty("kaptcha.textproducer.font.names", "宋体, 楷体, 微软雅黑");

        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

②实现获取验证码性能

创立 CaptchaController:

  • 留神:KaptchaConfig 配置类和 KaptchaController 控制器肯定要在同目录下。
@RestController
public class KaptchaController {

    // 这里的 captchaProducer 要和 KaptchaConfig 外面的 bean 命名一样
    @Autowired
    private Producer captchaProducer;

    @RequestMapping("/getCaptcha")
    public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 用字节数组存储
        byte[] captchaChallengeAsJpeg = null;
        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        ServletOutputStream responseOutputStream =
                response.getOutputStream();
        final HttpSession httpSession=request.getSession();
        try {
            // 生产验证码字符串并保留到 session 中
            String createText = captchaProducer.createText();
            // 打印随机生成的字母和数字
            System.out.println(createText);
            httpSession.setAttribute(Constants.KAPTCHA_SESSION_KEY, createText);
            // 应用生产的验证码字符串返回一个 BufferedImage 对象并转为 byte 写入到 byte 数组中
            BufferedImage challenge = captchaProducer.createImage(createText);
            ImageIO.write(challenge, "jpg", jpegOutputStream);
            captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
            response.setHeader("Cache-Control", "no-store");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpeg");
            // 定义 response 输入类型为 image/jpeg 类型,应用 response 输入流输入图片的 byte 数组
            responseOutputStream.write(captchaChallengeAsJpeg);
            responseOutputStream.flush();} catch (IllegalArgumentException e) {response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }finally {responseOutputStream.close();
        }
    }
}

两种办法的目录的区别

Captcha 配置阐明

google captcha 是 google 生成验证码的一个工具类,其原理是将随机生成字符串保留到 session 中,同时以图片的模式返回给页面,之后前台页面提交到后盾进行比照。

kaptcha.border 是否有边框 默认为 true 咱们能够本人设置 yes,no  
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

遇到的问题

Spring Boot 主动注入呈现 CONSIDER DEFINING A BEAN OF TYPE ‘XXX’ IN YOUR CONFIGURATION
失常状况下加上 @Component 注解的类会主动被 Spring 扫描到生成 Bean 注册到 spring 容器中,既然提醒没找到,也就是该注解被没有被 spring 辨认。
Spring 在默认状况下只能扫描与控制器在同一个包下以及其子包下的 @Component 注解,以及能将指定注解的类主动注册为 Bean 的 @Service、@Controller 和 @Repository。
两种解决办法:

  1. 将接口与对应的实现类放在与 application 启动类的同一个目录或者他的子目录下,这样注解能够被扫描到,这是最省事的方法
  2. 在指定的 application 类上加上注解@ComponentScan(basePackages = {"com.example.demo.service.impl", "com.example.dao"}),手动指定 application 类要扫描哪些包下的注解。

我的项目的 resources 文件夹下无奈创立 class 文件

留神到 resources 文件夹右下角的黄标,阐明此时文件夹的定义是不对的,按如下操作:

点击 Sources Root 之后:


参考:
https://www.xjyili.cn/3408.html
https://www.cnblogs.com/l024/…

正文完
 0