Bootstrap

SpringBoot02:YAML、数据校验和多环境切换

1 YAML

1.1 定义

1.1.1 概念

YAML是 YAML Ain’t a Markup Language (YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:Yet Another Markup Language(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。

你只要记住,这是一种新的文本格式即可

1.1.2 语法

基本的语法形式为:name: sharm

yaml 的书写规则:

  1. 冒号后面的空格不能省略!
  2. 大小写敏感;
  3. 使用缩进表示层级关系,缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级;
  4. 使用 # 表示注释;

1.1.3 常见场景的书写形式

# 这是 yaml 格式

# 普通的 key-value
name: sharm


# 对象或者 Map
people:
  name: sharm
  age: 24

# 对象或者 Map 的行内写法
people: {name: sharm, age: 24}

# 数组(List、Set)
people:
  - sharm
  - jack
  - luma

# 数组(List、Set)的行内写法
people: [sharm, jack, luma]

1.2 三种配置文件的区别

yaml 格式

# 这是 yaml 格式

# 普通的 key-value
name: sharm


# 对象或者 Map
people:
  name: sharm
  age: 24

xml 格式

<!-- 这是 xml 格式 -->

<name value="sharm"/>

<people>
    <name>sharm</name>
    <age>24</age>
</people>

properties 格式

# 这是 properties 格式

# 普通的 key-value
name = sharm


# 对象或者 Map
people.name = sharm
people.age = 24

1.3 利用 yaml 给实体类赋值

1.3.1 传统方式

1 在启动类的同级目录下编写一个实体类

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

// JavaConfig 的方式
// 该注解的作用是让该实体类被 Spring 扫描到,并被其托管
@Component
public class Student {
    // 可以通过@Value 可以实体类的私有域赋值
    @Value("Sharm")
    private String name;
    @Value("24")
    private Integer age;

    // 有参、无参构造
    // getter、setter 方法
    // 重写 toString 方法
}

2 利用 SpringBoot 的测试类进行测试

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import sharm.springboot.pojo.Student;

@SpringBootTest
class SpringbootApplicationTests {

    // 因为 Student 已经是容器的组件了,所以可以通过 Autowired 进行自动装配
    // 如果创建多个对象,可以用 @Qualifier 指定
    @Autowired
    Student student;

    @Test
    void contextLoads() {
        System.out.println(student);
    }
}

3 输出

请添加图片描述

1.3.2 使用 properties 方式

1 编写 application.properties 文件

student1.name=sharm
student1.age = 24

student2.name=jack
student2.age = 24

2 在启动类的同级目录下编写一个实体类

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

// JavaConfig 的方式
// 该注解的作用是让该实体类被 Spring 扫描到,并被其托管
@Component
@PropertySource(value = "classpath:application.properties")
public class Student {
    // 可以通过 @Value 可以实体类的私有域赋值
    //从配置文件中取值
    @Value("${student1.name}")
    private String name;
    // {SPEL} Spring 表达式
    @Value("#{2*12}")
    private Integer age;

    // 有参、无参构造
    // getter、setter 方法
    // 重写 toString 方法
}

3 利用 SpringBoot 的测试类进行测试

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import sharm.springboot.pojo.Student;

@SpringBootTest
class SpringbootApplicationTests {

    // 因为 Student 已经是容器的组件了,所以可以通过 Autowired 进行自动装配
    // 如果创建多个对象,可以用 @Qualifier 指定
    @Autowired
    Student student;

    @Test
    void contextLoads() {
        System.out.println(student);
    }
}

4 输出

请添加图片描述

1.3.3 yaml 方式

1 编写 application.yaml 文件

# 这是 yaml 格式
# 这部分的 Map 好迷糊,不过终于弄清楚了
school:
  name: ZJUT
  age: 69
  Happy: false
  birth: 1953/01/01
  schoolClass:
    control_engineer:
      name: sharm
      age: 24
    automation:
      name: teia
      age: 25
  classmate: [{name: jena, age: 24}, {name: luma, age: 25}]
  friend:
    name: tima
    age: 24

2 在启动类的同级目录下编写一个实体类

package sharm.springboot.pojo;


/*
@ConfigurationProperties作用:将配置文件中配置的每一个属性的值,映射到这个组件中;
参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应
*/

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "school")
public class School {
    private String name;
    private Integer age;
    private Boolean Happy;
    private Date birth;
    private Map<String, Student> schoolClass;
    private List<Student> classmate;
    private Student friend;
    
    // 有参、无参构造
    // getter、setter 方法
    // 重写 toString 方法
    
}

3 利用 SpringBoot 的测试类进行测试

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import sharm.springboot.pojo.School;
import sharm.springboot.pojo.Student;

@SpringBootTest
class SpringbootApplicationTests {

    // 因为 Student 已经是容器的组件了,所以可以通过 Autowired 进行自动装配
    // 如果创建多个对象,可以用 @Qualifier 指定
    @Autowired
    School school;

    @Test
    void contextLoads() {
        System.out.println(school);
    }
}

4 输出

School{name='ZJUT', age=69, Happy=false, birth=Thu Jan 01 00:00:00 CST 1953, schoolClass={control_engineer=Student{name='sharm', age=24}, automation=Student{name='teia', age=25}}, classmate=[Student{name='jena', age=24}, Student{name='luma', age=25}], friend=Student{name='tima', age=24}}

 


2 数据校验

2.1 示例

Springboot 中可以用 @Validated 来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。

比如如下的代码就是限定了学生的姓名不能为空:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

// JavaConfig 的方式
// 该注解的作用是让该实体类被 Spring 扫描到,并被其托管
@Component
@ConfigurationProperties(prefix = "student")
//数据校验
@Validated  
public class Student {
    // 限定名称不能为空
    @NotNull(message="名字不能为空")
    private String name;

    // 有参、无参构造
    // getter、setter 方法
    // 重写 toString 方法
}

2.2 数据校验的常见参数

@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;

空检查
@Null       验证对象是否为null
@NotNull    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty   检查约束元素是否为NULL或者是EMPTY.
    
Booelan检查
@AssertTrue     验证 Boolean 对象是否为 true  
@AssertFalse    验证 Boolean 对象是否为 false  
    
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=) string is between min and max included.

日期检查
@Past       验证 DateCalendar 对象是否在当前时间之前  
@Future     验证 DateCalendar 对象是否在当前时间之后  
@Pattern    验证 String 对象是否符合正则表达式的规则

.......等等
除此以外,我们还可以自定义一些数据校验规则

 


3 多环境切换

3.1 配置文件加载位置

多环境切换即是 SpringBoot 的配置文件的切换,Springboot 在启动时会扫描一些位置的 application.properties 或者application.yml 文件作为 Springboot 的默认配置文件,其中的优先级为:

优先级1:项目路径下的 config 文件夹配置文件
优先级2:项目路径下配置文件
优先级3:资源路径下的 config 文件夹配置文件
优先级4:资源路径下配置文件

Springboot 会从这四个位置全部加载配置文件,同时遵循互补配置;优先级由高到底,高优先级的配置会覆盖低优先级的配置;

3.2 多配置文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本,比如 application-test.properties 代表测试环境配置;application-dev.properties 代表开发环境配置。

但是 Springboot 并不会直接启动这些配置文件,它默认使用 application.properties 主配置文件;

我们需要通过一个配置来选择需要激活的环境,就像这样:

# 比如在配置文件中指定使用 dev 环境,我们可以通过设置不同的端口号进行测试;
# 我们启动 SpringBoot,就可以看到已经切换到 dev 下的配置了;
spring.profiles.active=dev

或者通过 yaml 的形式来配置:

server:
  port: 8081
#选择要激活那个环境块
spring:
  profiles:
    active: prod

---
server:
  port: 8083
spring:
  profiles: dev #配置环境的名称


---

server:
  port: 8084
spring:
  profiles: prod  #配置环境的名称

如果 yml 和 properties 同时都配置了端口,并且没有激活其他环境 , 默认会使用 properties 配置文件的。

;