🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
我们在前面讲解Tomcat的时候,默认的端口号是8080,如果我们有的程序访问的端口号也是8080的时候,这时候就会发生端口号冲突,所以我们需要通过配置文件来修改程序运行时的端口号.在项目创建的时候,就帮我们自动创建了一个配置文件.他的后缀是.properties
.
我们点开配置文件修改程序的端口号:
spring.application.name=demo server.port=9090
运行程序:我们可以发现程序的端口号变成了9090.
这时候我们通过8080端口号访问其中的html页面的时候,就无法访问了.
SpringBoot的配置文件有以下三种:
• application.properties
• application.yml
• application.yaml
其中yml格式和yaml格式其实是等同的.yml是yaml的缩写.
需要注意的一点是,配置文件的文件名只能是以上三个,文件名一旦修改,配置文件就会变成无效配置文件.
properties配置文件是最早期的配置文件格式,也是创建SpringBoot项目默认的配置文件
properties是以键值的形式配置的,单词和单词之间用.
分割,就像导包一样.key和value之间是以=
连接的.比如:
spring.application.name=demo server.port=9090 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8&useSSL=false spring.datasource.name=root spring.datasource.password=qwe123524
[提示] 配置文件中可以通过在前面加#
来注释信息.
如果在项目中,想要读取配置文件中的内容,可以使用@Value
注解来实现.@Value
注解在后面的参数中使用${}
的格式来读取,代码如下:
@RestController @RequestMapping("/demo") public class PropertiesController { @Value("${mykey.key}") private String key; @RequestMapping("/key") public String key(){ return key; } }
运行结果:
properties配置文件是以key-Value的形式来配置的,但是有的时候,配置文件中的信息有些赘余,比如下面的配置,spring.datasource
这个内容就是赘余的:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8&useSSL=false spring.datasource.name=root spring.datasource.password=qwe123524
要想解决这个问题,我们需要引入yml配置文件的格式了.
yml是树形结构的配置文件,他的基础语法是:key: value
,需要注意的一点是,key和value之间的空格不可以省略.
基础语法如下:
我们看到,要是yml的键值对中间没有空格的话,key是没有语法高亮的,语法就是错误的.
下面我们就把上面连接数据库的案例改写为yml的格式.
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8&useSSL=false name: root password: qwe123524
我们看到,前面我们所说的"赘余"的信息,在yml下可以合并到一起写了.这里行与行之间的缩进一般是两个空格.
# 字符串 string.value: Hello # 布尔值,true或false boolean.value: true boolean.value1: false # 整数 int.value: 10 # 浮点数 float.value: 3.14159 # Null,~代表null null.value: ~ # "" 空字符串 #, 直接后⾯什么都不加就可以了, 但这种⽅式不直观, 更多的表⽰是使⽤引号括起来 empty.value: ''
这里需要注意的地方只有两点,第一就是空字符串是一个单引号,第二就是null用一个波浪号来表示.
yml读取配置的方法和properties相同,使用@Value
注解即可,实现代码如下:
string: hello: bite
@RequestMapping("/demo") @RestController public class YmlController { @Value("${string.hello}") public String hello; @RequestMapping("/hello99") public String hello(){ return this.hello; } }
运行结果:
字符串默认不用加上单引号或者是双引号,如果加了的话,有的情况下又会表示特殊含义.
比如在yml文件中配置如下信息:
string: str1: Hello \n Spring Boot. str2: 'Hello \n Spring Boot.' str3: "Hello \n Spring Boot."
@RestController public class ReadYml { @Value("${string.str1}") private String str1; @Value("${string.str2}") private String str2; @Value("${string.str3}") private String str3; @PostConstruct public String readYml(){ System.out.println(str1); System.out.println(str2); System.out.println(str3); return "yml"; } }
在这里我们可以看到:
注意:这里的转义说起来可能会有些拗口,\n本来表示的是换行,使用单引号发生了转义,也就是说,\n不再表示换行了,表示的是一个普通的字符串,而加了双引号之后就表示的是特殊字符的本意,没有发生转义.
我们来说明一下
@PostConstruct
这个注解,这个注解表示的是,在服务启动之后,这个方法会变为初始化方法,这个方法在后端立即就会执行,如果有打印信息的话,会立即打印在后端的控制台上.相比于使用@RequestMapping
注解,我们就不需要通过浏览器来访问最终结果了,我们只需要在后端的控制台上看最终的结果即可.
我们还可以在yml中配置对象.如下配置:
student: id: 1 name: java age: 20
这个时候我们就不可以用@Value
来配置对象了,此时就要使用到另一个注解:@ConfigurationProperties
来读取.具体实现如下:
@Component @ConfigurationProperties(prefix = "student") @Data public class Student { public Integer id; public String name; public Integer age; }
@RestController public class StudentController { @Autowired private Student student; @PostConstruct public void readStudent(){ System.out.println(student); } }
运行结果:
[注意事项]
@Data
注解,我们下面不引入注解,手动写入Set方法,来验证这种说法的可靠性.@Component @ConfigurationProperties(prefix = "student") public class Student { public Integer id; public String name; public Integer age; public void setId(Integer id) { this.id = id; } public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
运行结果:
2. 在类的属性中,属性名必须和yml中的字段名是一致的.否则无法对应的上.
配置文件还可以配置List集合,(包括数组,Set在内都是如下的方法)如下所示:
dbtypes: name: - mysql - sqlserver - db2
就是在每一个字符串的前面加上一个横杠,就表示的是列表,和md的语法非常相似.
import java.util.List; @Component @Data @ConfigurationProperties(prefix = "dbtypes") public class ListConfig { public List name;//对应name字段 }
@RestController public class ReadYml2 { @Autowired public ListConfig listConfig; @PostConstruct public void readList(){ System.out.println(listConfig); } }
运行结果:
在配置集合的时候,上述代码实际上也是在配置一个对象,所以仍然使用@ConfigurationProperties
注解.
配置文件也可以配置map,如下所示:
maptypes: map: k1: v1 k2: v2 k3: v3
@Component @Data @ConfigurationProperties(prefix = "maptypes") public class MapConfig { //注意字段名的一致性 public Map map; }
@RestController public class ReadYml3 { @Autowired public MapConfig mapConfig; @PostConstruct public void mapReader(){ System.out.println(this.mapConfig); } }
运行结果:
请求url: /captcha/getCaptcha 请求参数: 无
请求url: /captcha/check 请求参数: captcha=用户输入的验证码
验证码的图片该怎么生成呢?我们就是通过这个工具来生成的.
官方网站: https://hutool.cn/
参考文档: https://hutool.cn/docs/#/
cn.hutool hutool-captcha 5.8.22
captcha: width: 100 height: 40 session: key: CAPTCHA_SESSION_KEY date: KAPTCHA_SESSION_DATE
配置项中对应的分别是验证码的长和宽,还有用于存储验证码和过期时间.
@Component @ConfigurationProperties(prefix = "captcha") @Data public class CaptchaProperties { public Integer width; public Integer height; public Session session; public static class Session{ public String key; public String date; } }
@RestController @RequestMapping("/captcha") public class CaptchaController { @Autowired public CaptchaProperties captchaProperties; @RequestMapping("/getCaptcha") public void getCaptcha(HttpServletResponse response, HttpSession session) throws IOException {//可以通过这个参数拿到响应中的所有信息 LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(captchaProperties.getWidth(),captchaProperties.getHeight());//创建线条干扰验证码 //图形验证码写出,可以写出到文件,也可以写出到流 response.setContentType("image/jpeg");//从响应中获取到类型信息,设置为图片格式 response.setHeader("Pragma","No-cache");//从响应中获取到Header,把Pragma键值对设置为没有缓存. try { lineCaptcha.write(response.getOutputStream()); //把验证码放入session中 session.setAttribute(captchaProperties.getSession().getKey(),lineCaptcha.getCode()); //把过期时间放入session中 session.setAttribute(captchaProperties.getSession().getDate(),System.currentTimeMillis()); response.getOutputStream().close();//关闭输出流 } catch (IOException e) { throw new RuntimeException(e); } } }
接下来我们来访问网页来观察验证码是否生成成功.
验证码生成成功.
public static final Integer MAX_WAIT_MILLS = 60*1000; @RequestMapping("/check") public boolean checkCaptcha(HttpSession session,String captcha){ if (!StringUtils.hasLength(captcha)){//判断验证码是否有长度 return false; } String sessionCode = (String) session.getAttribute(captchaProperties.getSession().getKey()); Long sessionDate = (Long) session.getAttribute(captchaProperties.getSession().getDate()); if (captcha.equalsIgnoreCase(sessionCode) && System.currentTimeMillis()-sessionDate < MAX_WAIT_MILLS){ return true;//验证码和用户输入的等同且 } return false; }
验证码 输入验证码
验证成功页 验证成功
测试运行: