【Trainee】07/22 第一个任务:使用jar包captcha实现验证码

虽然老大说这是一个特简单的小项目,但是我这个没有接触过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,如图所示:
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第1张图片
在这里选择好JDK版本。
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第2张图片
这一步要注意Java Version的选择。
按需选择,这里我创建Spring Web项目:
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第3张图片
这一步注意Spring Boot版本的选择。

这里在界面左上角可以搜索并添加需要添加的依赖(Dependencies)如Lombok、Thymeleaf等,当然依赖也可以在生成项目之后在pom.xml文件中手动添加。
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第4张图片

【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第5张图片
给项目取个名字吧!
创建成功后这些文件可以删除:
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第6张图片
成功:
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第7张图片

导入kaptcha依赖

在pom.xml文件中添加:



    com.github.penggle
    kaptcha
    2.3.2

Step2:分析

有两种方式在Spring Boot中使用kaptcha:

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

Step3.1:方法1

①创建KaptchaConfig.xml



    
        
            
                
                    
                        
                        yes
                        
                        105,179,90
                        
                        blue
                        
                        100
                        
                        50
                        
                        27
                        
                        code
                        
                        4
                        
                        宋体,楷体,微软雅黑
                        
                        0123456789ABCEFGHIJKLMNOPQRSTUVWXYZ
                        
                        com.google.code.kaptcha.impl.WaterRipple
                        
                        black
                        
                        com.google.code.kaptcha.impl.DefaultNoise
                        
                        185,56,213
                        
                        white
                        
                        3
                    
                
            
        
    

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

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

【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第8张图片

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

【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第9张图片

两种方法的目录的区别

【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第10张图片

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文件
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第11张图片

注意到resources文件夹右下角的黄标,说明此时文件夹的定义是不对的,按如下操作:
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第12张图片

点击Sources Root之后:
【Trainee】07/22 第一个任务:使用jar包captcha实现验证码_第13张图片


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

你可能感兴趣的:(springboot,captcha)