一:配置文件
(1)配置文件的作用
💗配置文件主要是为了解决硬编码带来的问题
(硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中, 即我们常说的"代码写死")
🌟举例:手机字体大小如果是硬编码的方式, 就直接在程序中指定字体大小, 所有的用户使用的都是同⼀个字体大小,但是不同的用户有不同的偏好, 我们可以把⼿机字体的大小放在配置文件中, 当程序启动时, 读取配置,以用户设置的字体大小来显示
(2)SpringBoot配置文件
💗很多项目或者框架的配置信息也放在SpringBoot配置文件中
🌟比如:
1.项目的启动端口(即可修改Tomcat的默认端口,不再是8080)
2.数据库的连接信息(包含用户名和密码的设置)
3.第三方系统的调用密钥等信息
4.用于发现和定位问题的普通日志和异常日志等
(3)配置文件的格式
1.三种格式
①application.properties
(SpringBoot项目默认的配置文件,创建自带的)
②application.yml
(yml为yaml的简写, 实际开发中出现频率最高)
③application.yaml
(yaml和yml的使用方式⼀样,文章就不讲yaml了)
2.properties和yml
①两者区分:类似商品的包装⼀样,有新老两款包装
(1)properties:属于老款包装,也是创建Spring Boot项目时默认的文件格式
(2)yml:属于新版包装,如果用户了解情况直接指定要新款包装,那么就直接发给他
②properties的优先权比yml更高
理论上讲,properties和yml可以并存于⼀个项目中,当properties和yml并存时,两个配置都会加载;如果配置文件内容有冲突,则以properties为主
③虽然properties和yml可以并存,但在实际开发中我们通常会采取统⼀的配置文件格式
④它们的名字不可以乱改,必须是application.properties和application.yml
(4)创建配置文件
💗右键resource目录➜New➜File➜按照三种配置文件格式取名即可
(5)更多的配置文件与配置项
💓参考官网:Common Application Properties
二:properties配置文件
(1)properties配置文件说明
🌟properties配置文件是最早期的配置文件格式,也是创建SpringBoot项目默认的配置文件
💚位于Spring项目的src/main/resources目录下
(2)properties语法格式
💗properties是以键值的形式配置的,key之间用"."分割;key和value之间是以"="连接的
(无论是什么样的数据类型,比如字符串还是数字,直接写即可)
![]()
(3)properties读取配置文件
1.方法
💗使用@Value注解;具体格式是@Value("${ }") ;{ }里填的就是配置文件的key;然后通过@RequestMapping访问URL读取配置文件
2.代码演示
①首先在application.properties中自定义一个配置
②在Controller目录下创建一个PropertiesController类
package com.example.demo.Controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class PropertiesController { //读取配置文件 @Value("${demo.key1}") private String key1; @RequestMapping("/readKey") public String readKey(){ return "读取到的配置项key1:"+key1; } }
③观察结果
(4)properties缺点分析
💗properties配置文件中会有很多的冗余的信息,即很多重复且不必要的信息
🌟如下图所示,有太多重复的spring.datasource了
💚解决办法:下文的yml配置文件
三:yml配置文件
(1)yml配置文件说明
🌟yml是YAML的缩写,它的全称Yet Another Markup Language
💚并非一创建Spring项目就有的,这个需要自行创建
(2)yml语法格式
💗yml是树形结构的配置文件,key和value之间是以":"分割的
🌟注意冒号之后一定要先空格再写value
(空格一定一定不能省略!!!)
(3)yml与properties的语法对比
💗properties转换成yml方式:把"."改成":"加上换行
💗yml转换成properties方式:把":"改成"."去掉换行
(4)yml读取配置文件
1.方法一
💗使用@Value注解;具体格式是@Value("${ }") ;{ }里填的就是配置文件的key;然后通过@RequestMapping访问URL读取配置文件
💚注意事项
①这个key要变形,变成properties的格式,即":"换成"."
②通过@RequestMapping注解访问URL的方式来读取
2.代码演示(方法一)
①首先在application.yml中自定义一个配置
②在Controller目录下创建一个YmlController类
(注意@Value的格式,yml格式转为了properties格式了)
package com.example.demo.Controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class YmlController { @Value("${demo.key1}") private String key1; @RequestMapping("/readyml") public String readYml(){ return "得到的key1为:"+key1; } }
③观察结果
3.方法二
💗使用@Value注解;具体格式是@Value("${ }") ;{ }里填的就是配置文件的key;然后通过@PostConstruct直接显示在控制台上
💚注意事项
①这个key要变形,变成properties的格式,即":"换成"."
②直接在控制台显示出来,不需要通过访问URL的方式
💜认识@PostConstruct注解
作用:在属性注入完成之后,它就会执行对应的方法
4.代码演示(方法二)
①首先在application.yml中自定义一个配置
②修改YmlController类的代码
package com.example.demo.Controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; @RestController public class YmlController { @Value("${demo.key1}") private String key1; @Value("${demo.key2}") private String key2; @Value("${demo.key3}") private String key3; //@Value属性注入完成之后,@PostConstruct就会执行init方法 @PostConstruct public void init(){ System.out.println("key1:"+key1); System.out.println("key2:"+key2); System.out.println("key3:"+key3); } }
③观察结果
(可以看到在Tomcat启动之前就已经打印出来了)
(5)yml配置不同数据类型及null
💗yml特殊内容配置
①null:用~表示
②空字符串:key后面直接空着就就行;但不雅观,建议加上单/双引号
💗关于yml配置文件中的单引号和双引号
①字符串默认不用加上单引号或者双引号
②单引号会让特殊字符失去特殊功能,始终是⼀个普通的字符串
③双引号不会转义字符串里面的特殊字符,特殊字符会表示本身的含义
(6)yml配置对象
1.yml配置对象语法格式
①方式一:
②方式二:
2.读取配置中的对象
💗方法:使用@ConfigurationProperties注解,配合prefix属性,表示这个类里的属性在yml配置文件中的前缀是什么,完成属性注入
(此时不能使用@Value注解了)
①先创建一个Student类,使用@ConfigurationProperties读取yml配置文件前缀为student的数据并赋值给Student的三个属性
(注意这里的prefix是student,是因为在yml文件中id、name和age的前缀都是student;并且还加了五大类注解,表示把这个Student对象存到Spring,即交给Spring管理,后续需要可拿出来)
package com.example.demo; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "student") @Data public class Student { private Integer id; private String name; private Integer age; }
②修改YmlController类中的代码
(注意这里使用@Autowired完成属性注入,拿到了Student对象)
package com.example.demo.Controller; import com.example.demo.Student; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; @RestController public class YmlController { @Autowired private Student student; //@Value属性注入完成之后,@PostConstruct就会执行init方法 @PostConstruct public void init(){ System.out.println("Student:"+student); } }
③观察结果
(7)yml配置集合
1.yml配置集合语法格式
💗使用-来表示一个集合里的数据( - 之后也记得别忘了空格!)
2.读取配置中的对象
💗方法:使用@ConfigurationProperties注解,配合prefix属性,表示这个类里的属性在yml配置文件中的前缀是什么,完成属性注入
①先创建一个DBType类,使用@ConfigurationProperties读取yml配置文件前缀为dbtypes的数据并赋值给DBType的name数组
package com.example.demo.model; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.List; @Component @ConfigurationProperties(prefix = "dbtypes") @Data public class DBType{ private List<String> name; }
②修改YmlController类中的代码
package com.example.demo.Controller; import com.example.demo.model.DBType; import com.example.demo.model.Student; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; import javax.annotation.PostConstruct; @RestController public class YmlController { @Autowired private DBType dbType; //@Value属性注入完成之后,@PostConstruct就会执行init方法 @PostConstruct public void init(){ System.out.println("dbTypes:"+dbType); } }
③观察结果
(8)yml配置Map
🌟与上述yml配置集合一模一样,只不过从List变成了MAP而已,这里不再赘述
(8)yml的优点
①可读性高,写法简单,易于理解
②支持更多的数据类型,可以简单表达对象,数组,List,Map等数据形态
③支持更多的编程语言,不止是Java中可以使用,在Golang, Python, Ruby, JavaScript中也可以使用
(9)yml的缺点
①不适合写复杂的配置文件
②对格式有较强的要求,空格相信都深有体会
四:Kaptcha插件
(1)Kaptcha插件介绍
💛Kaptcha是Google的⼀个高度可配置的实用验证码生成工具
(2)Kaptcha插件原理
💗Kaptcha插件选择把验证码存储在Session里
🌟对于普通的字符验证码,后端通常分两部分:
①生成验证码内容,根据验证码内容和干扰项等,生成图片,返回给客户端
②把验证码内容存储起来,校验时取出来进行对比
(验证码既可以由客户端生成,也可以由服务器生成)
(3)Kaptcha插件依赖
<dependency> <groupId>com.oopsguy.kaptcha</groupId> <artifactId>kaptcha-spring-boot-starter</artifactId> <version>1.0.0-beta-2</version> </dependency>
(4)Kaptcha插件生成验证码
1.通过代码生成验证码
🌟本篇文章不细说,感兴趣的可点击链接自行查看➜Kaptcha Spring Boot
2.通过配置文件生成验证码
🌟比较推荐
(5)Kaptcha演示说明
1.kaptcha.items
💗kaptcha.items是⼀个Map,key为验证码生成器名称,value为验证码生成器的配置
2.先在pom.xml加入依赖
3.在application.yml中加入以下代码
kaptcha: items: # home captcha home: path: /home/captcha session: key: HOME_KAPTCHA_SESSION_KEY date: HOME_KAPTCHA_SESSION_DATE
4.运行启动类
💛运行完启动类后,输入127.0.0.1:8080/home/captcha即可生成图片
五:验证码校验练习
(1)需求
①页面生成验证码
②输入验证码,点击提交,验证用户输入验证码是否正确,正确则进行页面跳转
(2)前端代码
💗前端代码网盘链接:前端代码(网盘密码:lzh7)
(3)准备工作
🌟①将前端代码引入到static目录下
🌟②运行后端并访问,确保没有错误
(1)index.html
(2)success.html
(4)约定前后端交互接口
1.需求分析
💚后端需要提供一个服务:
校验验证码是否正确
2.校验验证码是否正确的交互接口
(5)后端代码
💗校验验证码是否正确
(因为是后端生成的验证码,所以要在后端完成校验)
(1)先创建一个Controller包,然后创建CaptchaController类
(2)后端代码
package com.hlizoo.demo.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession; import java.util.Date; @RequestMapping("/admin") @RestController public class CaptchaController { private static final String KAPTCHA_SESSION_KEY = "HOME_KAPTCHA_SESSION_KEY"; private static final String KAPTCHA_SESSION_DATE = "HOME_KAPTCHA_SESSION_DATE"; private static final Long SESSION_TIMEOUT = 60*1000L; //如果验证成功返回true;失败返回false //如果想要校验,就得获取前端从输入框输入的值,因此用captcha作为参数接收 /* 校验思路: 1.从application.yml可以得知验证码是存放到session中的,因此我们可以直接从session获取生成的验证码 2.比对前端传递过来的验证码,即用参数captcha和session获取的验证码进行对比 */ @RequestMapping("/check") public boolean check(String captcha, HttpSession session){ //第一步:先判断前端输入框中用户是否有输入值 if(!StringUtils.hasLength(captcha)){ return false; } //第二步:从session中获取验证码;也获取时间 String saveCaptcha = (String) session.getAttribute(KAPTCHA_SESSION_KEY); Date saveDate = (Date) session.getAttribute(KAPTCHA_SESSION_DATE); //第三步:比对验证码 if(captcha.equals(saveCaptcha)){ //判定验证码如果超过1分钟就失效 if(saveDate==null || System.currentTimeMillis()-saveDate.getTime()<SESSION_TIMEOUT){ return true; } } return false; } }
(6)前端代码
💗校验验证码是否正确
(1)先用VSCode打开index.html
(2)修改前端代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>验证码</title> <style> #inputCaptcha { height: 30px; vertical-align: middle; } #verificationCodeImg{ vertical-align: middle; } #checkCaptcha{ height: 40px; width: 100px; } </style> </head> <body> <h1>输入验证码</h1> <div id="confirm"> <input type="text" name="inputCaptcha" id="inputCaptcha"> <img id="verificationCodeImg" src="/admin/captcha" style="cursor: pointer;" title="看不清?换一张" /> <input type="button" value="提交" id="checkCaptcha"> </div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script> $("#verificationCodeImg").click(function(){ $(this).hide().attr('src', '/admin/captcha?dt=' + new Date().getTime()).fadeIn(); }); $("#checkCaptcha").click(function () { $.ajax({ type:'get', url:'/admin/check', data:{ captcha:$("#inputCaptcha").val() }, //里面的result就是后端返回的结果 success:function(result){ if(result){ location.href='success.html'; }else{ alert("验证码错误"); } } }); }); </script> </body> </html>