虽然老大说这是一个特简单的小项目,但是我这个没有接触过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,如图所示:
image.png
在这里选择好JDK版本。
image.png
这一步要注意Java Version的选择。
按需选择,这里我创建Spring Web项目:
image.png
这一步注意Spring Boot版本的选择。

这里在界面左上角可以搜索并添加需要添加的依赖(Dependencies)如Lombok、Thymeleaf等,当然依赖也可以在生成项目之后在pom.xml文件中手动添加。
image.png

image.png
给项目取个名字吧!
创建成功后这些文件可以删除:
批注 2020-07-29 135724.png
成功:
image.png

导入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();
    }
}

image.png

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();
        }
    }
}

image.png

两种方法的目录的区别

image.png

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文件
批注 2020-07-29 165755.jpg

注意到resources文件夹右下角的黄标,说明此时文件夹的定义是不对的,按如下操作:
image.png

点击Sources Root之后:
image.png


参考:
https://www.xjyili.cn/3408.html
https://www.cnblogs.com/l024/...
Github:https://github.com/colderThyK...


已注销
9 声望0 粉丝