一、 Spring Boot配置文件分类
SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置
application.properties 语法结构 :key=value
application.yml 语法结构 :key:空格 value (冒号后面必须要有空格)
小结
SpringBoot 提供了 2 种配置文件类型: properteis 和 yml/yaml
默认配置文件名称: application
在同一级目录入如果三类文件共存,优先级为:properties > yml > yaml
二、YAML概述
YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如:C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。
YAML文件的扩展名可以使用**.yml** 或者**.yaml**。
server.port=8080
<server>
<port>8080</port>
</server>
server:
port: 8080
三、YAML基础语法
1.要点
1. 大小写敏感
2. 数据值前边必须有空格,作为分隔符
3. 使用缩进表示层级关系
4. 缩进时不允许使用Tab键,只允许使用空格(各个系统 Tab对应的 空格数目可能不同,导致层次混乱)。
5. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
6. "#"表示注释,从这个字符一直到行尾,都会被解析器忽略。
2.YAML:数据格式
字面量:(空格)普通的值 [ 数字,布尔值,字符串 ]
boolean: TRUE #TRUE,true,True,FALSE,false,False均可
float: 3.14 #6.8523015e+5 #支持科学计数法
int: 123 #0b1010_0111_0100_1010_1110 #支持二进制、八进制、十六进制
string: HelloWorld #字符串可以直接书写
数组:一组按次序排列的值( List、set )
address:
- beijing
- shanghai
# 行内写法
commpany: [阿里巴巴,华为,腾讯,字节跳动]
对象、Map(键值对)
person:
name: wangzhuo
# 行内写法
person: {name: wangzhuo}
#对象数组格式一
users:
- name: Tom
age: 4
- name: Jerry
age: 5
#对象数组格式二
users:
-
name: Tom
age: 4
-
name: Jerry
age: 5
#对象数组缩略格式
users2: [ { name:Tom,age:4 },{ name:Jerry,age:5 } ]
参数引用
name: tom
person:
name: women
pet: ${name} #引用上面定义的name值
YAML小结
1) 配置文件类型
- properties:和以前一样 (设置文件的语言编码UTF-8)
- yml/yaml:注意空格
2) yaml:简洁,以数据为核心
- 基本语法
- 大小写敏感
- 数据值前边必须有空格,作为分隔符
- 使用空格缩进表示层级关系,相同缩进表示同一级
- 数据格式
- 对象
- 数组: 使用 " - "表示数组每个元素
- 纯量
- 参数引用
- ${key}
四、读取配置内容
yaml文件更强大的地方在于,可以给我们的实体类直接注入匹配值
逐个注入:@Value
批量注入:
- @ConfigurationProperties
- Environment类
1.逐个注入1:@Value("")
@Component //注册bean
public class Dog {
@Value("阿黄")
private String name;
@Value("18")
private Integer age;
}
2.逐个注入2:@Value("${}")
@PropertySource:加载指定的配置文件
去在resources目录下新建一个dog.yml文件
name: 阿黄
age: 18
@PropertySource(value = "classpath:dog.yml")
@Component //注册bean
public class Dog{
@Value("${name}")
private String name;
@Value("${age}")
private Integer age;
}
3.批量注入1:@ConfigurationProperties
@Component //注册bean到容器中
public class Person {
private String name;
private integer age;
private boolean marry;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
//有参无参构造、get、set方法、toString()方法
}
编写yaml文件内容:
person1:
name: wangls
age: 18
marry: true
birth: 1990/10/19
maps: {k1: v1,k2: v2}
lists:
- code
- bodybuilding
- music
dog:
name: summer
age: 1
@ConfigurationProperties作用:将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定
参数 prefix = "person1" : 将配置文件中的person1下面的所有属性一一对应
4批量注入2:Environment类
在测试类中装配开发模式类辅助获取key对应value数据
@Autowired
private Environment env;
@Test
public void test(){
System.out.println(env.getProperty("person1.name"));
System.out.println(env.getProperty("person1.age"));
System.out.println(env.getProperty("person1.dog.name"));
System.out.println(env.getProperty("person1.lists[0]"));
}
5.对比小结
|------------|--------------------------|----------|
| 对比 | @ConfigurationProperties | @Value() |
| 功能 | 批量注入配置文件中的属性 | 一个个指定 |
| 松散语法 | 支持 | 不支持 |
| SqEL | 不支持 | 支持 |
| JSR303数据校验 | 支持 | 不支持 |
| 复杂类型封装 | 支持 | 不支持 |
1、@ConfigurationProperties只需要写一次即可,@Value则需要每个字段都添加
2、松散绑定: 比如我的yml中写的last-name,这个和lastName是一样的, -后面跟着的字母默认是大写的。
3、JSR303数据校验,这个就是我们可以在字段是增加一层过滤器验证 ,可以保证数据的合法性
4、复杂类型封装,yml中可以封装对象 , 使用value就不支持
6.结论:
- 配置yml和配置properties都可以获取到值 , 强烈推荐 yml;
- 如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下 @value;
- 如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties
五、JSR303数据校验
对于 web 服务来说,为防止非法参数对业务造成影响,在 Controller 层一定要做参数校验的!大部分情况下,请求参数分为如下两种形式:
-
POST 、 PUT 请求,使用 requestBody 传递参数;
-
GET 请求,使用 requestParam/PathVariable 传递参数。
1.什么是 JSR303 标准?
- JSR的全称是Java Specification Requests(Java 规范提案),是指向JCP ( Java Community Process )提出新增一个标准化技术规范的正式请求。
- Java API 规范( JSR303 )定义了 Bean 校验的标准 validation-api ,但没有提供实现。
- hibernate validation 是对这个规范的实现,并增加了校验注解如 @Email 、 @Length 等。 Spring Validation 是对 hibernate validation 的二次封装,用于支持 spring mvc 参数自动校验。
2.JSR303校验注解的使用步骤
1.添加依赖,导入spring-boot-starter-validation启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.在实体类需要校验的成员字段(Field)上,添加校验注解。
@Component //注册bean到容器中
//@ConfigurationProperties(prefix = "dog")
//@Validated
public class Dog {
@NotNull(message = "狗名不能为空")
private String name;
@NotNull(message = "狗命不能为空")
@Max(value = 15,message = "狗命拿来")
private Integer age;
@Min(value = -1,message = "狗还是个细胞")
private Integer length;
@Email(message = "邮箱必须合法")
private String email;
}
3.在Controller控制器的校验参数前,使用@Valid注解开启校验,使用BindingResult 绑定校验结果
@RequestMapping("/validationDemo")
public String validationDemo(@Valid Dog dog, BindingResult result){
//得到所有错误信息计数
int errorCount = result.getErrorCount();
//错误数大于0
if (errorCount>0){
//得到所有错误
List<FieldError> fieldErrors = result.getFieldErrors();
//迭代错误
for (FieldError fieldError:fieldErrors) {
//错误信息
System.out.println( "属性:{"+fieldError.getField()+"},传来的值是:{"+fieldError.getRejectedValue()+"},出错的提示消息:{"
+fieldError.getDefaultMessage()+"}");
}
return "数据不合法";
}else{
return "数据合法";
}
}
3.JSR303校验注解的分类
- 值校验
- 范围校验
- 长度校验
- 格式校验
六、Controller统一异常处理
@ControllerAdvice:统一为Controller进行增强
@ExceptionHandler:异常处理
@ControllerAdvice
public class BindExceptionUtilAdvice {
// 验证参数未使用@RequestBody注解
@ExceptionHandler(BindException.class)
@ResponseBody//选择添加
public String handlerBindException(BindException ex, HttpServletRequestrequest){
return "全局异常处理器成功";
// 跳转至统一提示错误信息的视图
}
}
七、多环境切换profile
我们在开发Spring Boot应用时,通常同一套程序会被安装到不同环境,比如:开发、测试、生产等。其中数据库地址、服务 器端口等等配置都不同,如果每次打包时,都要修改配置文件,那么非常麻烦。profile功能就是来进行动态配置切换的。
命名语法:
例如:application-环境简称.properties/yml
application-dev.properties/yml 开发环境
application-test.properties/yml 测试环境
application-pro.properties/yml 生产环境
1) profile配置方式多profile文件方式
2) profile激活方式
配置文件 :
spring:
profiles:
active: 环境简称
虚拟机参数 :在VM options 指定:-Dspring.profiles.active=dev
命令行参数:java --jar xxx.jar --spring.profiles.active=dev