Spring Boot 2.X 对 web 的支持开发

上章节的 Spring Boot 的入门案例,我们感受到 Spring Boot 简单的配置即可运行项目。

今天了解 Spring Boot 对 web 的支持。

Spring Boot 对 Web 开发的支持很全面,包括开发、测试和部署阶段都做了支持。spring-boot-starter-web
是 Spring Boot 对 Web 开发提供支持的组件,主要包括 RESTful,参数校验、使用 Tomcat 作为内嵌容器器等功能。

Spring Boot 2.X 常用注解说明
get: 查询一些信息                       post:提交一些需要服务器保存的信息
put: 更新,更新一些用户信息           delete:删除信息
@GetMapping = @RequestMapping(method = RequestMethod.GET)
@PostMapping = @RequestMapping(method = RequestMethod.POST)
@PutMapping = @RequestMapping(method = RequestMethod.PUT)
@DeleteMapping = @RequestMapping(method = RequestMethod.DELETE)

eg: @RequestMapping(value="/user",method = RequestMethod.GET)等同于 @GetMapping(value = "/user")

如果指定以 Post 的方式去请求,然后使用 Get 的方式(或其他非 post 请求方式)去请求的话,则会报 405 不允许访问的错误。如果不进⾏设置默认两种方式的请求都支持。
get: 查询一些信息                       post:提交一些需要服务器保存的信息
put: 更新,更新一些用户信息           delete:删除信息
@GetMapping = @RequestMapping(method = RequestMethod.GET)
@PostMapping = @RequestMapping(method = RequestMethod.POST)
@PutMapping = @RequestMapping(method = RequestMethod.PUT)
@DeleteMapping = @RequestMapping(method = RequestMethod.DELETE)

eg: @RequestMapping(value="/user",method = RequestMethod.GET)等同于 @GetMapping(value = "/user")

如果指定以 Post 的方式去请求,然后使用 Get 的方式(或其他非 post 请求方式)去请求的话,则会报 405 不允许访问的错误。如果不进⾏设置默认两种方式的请求都支持。
Spring Boot 对 JSON的支持以及常用 JSON 注解使用

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。现在大部分的数据交互方式都采用 JSON。 而 Spring Boot 对 JSON 支持很完善,在 Web 层仅需要一个注解即可。

性能:Jackson > FastJson > Gson > Json-lib 同个结构。

jackson处理相关自动(在实体类字段上使用以下注解)
指定字段不返回:@JsonIgnore
指定日期格式:@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss",locale="zh",timezone="GMT+8")
空字段不返回:@JsonInclude(Include.NON_NUll) --->对于字符串类型的不返回,int类型的返回0
指定别名: @JsonProperty("XXXX")
jackson处理相关自动(在实体类字段上使用以下注解)
指定字段不返回:@JsonIgnore
指定日期格式:@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss",locale="zh",timezone="GMT+8")
空字段不返回:@JsonInclude(Include.NON_NUll) --->对于字符串类型的不返回,int类型的返回0
指定别名: @JsonProperty("XXXX")
Spring Boot 常见 web 中的传递参数方式

① 使用 URL 进行传参:@PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中,如 URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。

@RequestMapping(value="get/{name}", method=RequestMethod.GET)
public String get(@PathVariable String name) {
  return name;
}
在浏览器中输入网址:http://localhost:8080/get/Rookie,返回:Rookie,说明 name 值已经成功传入。
@RequestMapping(value="get/{name}", method=RequestMethod.GET)
public String get(@PathVariable String name) {
  return name;
}
在浏览器中输入网址:http://localhost:8080/get/Rookie,返回:Rookie,说明 name 值已经成功传入。

②数据校验:Web开发中最常见的就是输入数据的校验。

在 Spring MVC 中有两种方式可以验证输入:Spring 自带的验证框架和利用 JSR 实现。

JSR 是一个规范文档,指定了一整套 API,通过标注给对象属性添加约束。

Hibernate Validator 就是 JSR 规范的具体实现。

Spring Boot 的参数校验依赖于 hibernate-validator 来进行。

使用 Hibernate Validator 校验数据,需要定义一个接收的数据模型,使用注解的形式描述字段校验的 规则。

实体类:
    @Getter
    @Setter
    @ToString
    @AllArgsConstructor
    @NoArgsConstructor
    public class Person {
        @NotEmpty(message="姓名不能为空")
        private String name;

        @Max(value = 100, message = "年龄不能大于100岁")
        @Min(value= 18 ,message= "必须年满18岁!" )
        private int age;

        @NotEmpty(message="密码不能为空")
        @Length(min=6,message="密码长度不能小于6位")
        private String pass;
    }

请求接口:
  @RestController
  public class PersonController {

      @RequestMapping("/savePerson")
      public void savePerson(@Valid Person person, BindingResult result) {

          System.out.println("Person:"+person);
          if(result.hasErrors()){
              List<ObjectError> errorList = result.getAllErrors();
              errorList.stream().forEach(error->          System.out.println(error.getCode()+"====="+error.getDefaultMessage()));
              }
          }
      }

编写测试类:
    @Test
    public void savePerson() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.post("/savePerson")
                .param("name","")
                .param("age","666")
                .param("pass","test")
        );
    }

测试结果显示:
Person:Person(name=, age=666, pass=test)
Length=====密码长度不能小于6位
Max=====年龄不能大于100岁
NotEmpty=====姓名不能为空

结果显示已触发了校验规则,返回错误信息。在实际开发过程中可对错误信息进行包装,最后返回到前端展示。

@Valid:参数前面添加 @Valid 注解,代表此对象使用了参数校验;
BindingResult:参数校验的结果会存储在此对象中,可以将错误信息打印出来。
Hibernate Validator 基本上包含了常用的数据校验,包括校验属性是否为空、长度、大小、特定格式等完整的注解自己查表对比。
实体类:
    @Getter
    @Setter
    @ToString
    @AllArgsConstructor
    @NoArgsConstructor
    public class Person {
        @NotEmpty(message="姓名不能为空")
        private String name;

        @Max(value = 100, message = "年龄不能大于100岁")
        @Min(value= 18 ,message= "必须年满18岁!" )
        private int age;

        @NotEmpty(message="密码不能为空")
        @Length(min=6,message="密码长度不能小于6位")
        private String pass;
    }

请求接口:
  @RestController
  public class PersonController {

      @RequestMapping("/savePerson")
      public void savePerson(@Valid Person person, BindingResult result) {

          System.out.println("Person:"+person);
          if(result.hasErrors()){
              List<ObjectError> errorList = result.getAllErrors();
              errorList.stream().forEach(error->          System.out.println(error.getCode()+"====="+error.getDefaultMessage()));
              }
          }
      }

编写测试类:
    @Test
    public void savePerson() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.post("/savePerson")
                .param("name","")
                .param("age","666")
                .param("pass","test")
        );
    }

测试结果显示:
Person:Person(name=, age=666, pass=test)
Length=====密码长度不能小于6位
Max=====年龄不能大于100岁
NotEmpty=====姓名不能为空

结果显示已触发了校验规则,返回错误信息。在实际开发过程中可对错误信息进行包装,最后返回到前端展示。

@Valid:参数前面添加 @Valid 注解,代表此对象使用了参数校验;
BindingResult:参数校验的结果会存储在此对象中,可以将错误信息打印出来。
Hibernate Validator 基本上包含了常用的数据校验,包括校验属性是否为空、长度、大小、特定格式等完整的注解自己查表对比。
Spring Boot 常用获取读取配置文件的注解详解
@PropertySource 指定配置文件位置
@ConfigurationProperties  标注该注解的类与配置文件进行绑定,通过设置的前缀,来进行属性设置。

代码演示:
Author 类:
    @Component
    @PropertySource("author.properties")
    @ConfigurationProperties(prefix = "author")
    public class Author {

        //Value("${author.name}")
        private String name;

        //Vlue("${author.age}")
        private int age;
    }

author.properties 配置文件
  # 配置作者信息
    author.name=rookie
    author.age=18

启动类:
    @RestController
    @SpringBootApplication
    public class ConfigFileDemoApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigFileDemoApplication.class, args);
        }

        @Autowired
        private Author author;

        @GetMapping("/author")
        public String getAuthor(){

            return "姓名:"+author.getName()+"==========="+"年龄:"+author.getAge();
        }

    }
@PropertySource 指定配置文件位置
@ConfigurationProperties  标注该注解的类与配置文件进行绑定,通过设置的前缀,来进行属性设置。

代码演示:
Author 类:
    @Component
    @PropertySource("author.properties")
    @ConfigurationProperties(prefix = "author")
    public class Author {

        //Value("${author.name}")
        private String name;

        //Vlue("${author.age}")
        private int age;
    }

author.properties 配置文件
  # 配置作者信息
    author.name=rookie
    author.age=18

启动类:
    @RestController
    @SpringBootApplication
    public class ConfigFileDemoApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigFileDemoApplication.class, args);
        }

        @Autowired
        private Author author;

        @GetMapping("/author")
        public String getAuthor(){

            return "姓名:"+author.getName()+"==========="+"年龄:"+author.getAge();
        }

    }

因为我们在 Author 类中已经加了 @Component 注解,因此可以将此注解下的类作为 bean 注入到 Spring 容器中,方便使用。

使用频次最高的就是 @PropertySource & @ConfigurationProperties 配合使用,需要注意的是当在 resources 下再创建 config 文件夹,再将 author.properties 放进 config 文件夹时,需要修改@PropertySource("classpath:config /author.properties") 才可以正确读取配置路径。

当没使用 @ConfigurationProperties(prefix = "author") 注解的时,要想得到配置文件中属性,则需要结合以下注解进行数据源的配置(以上面 Author 类注释掉的部分为例):

@Value("${author.name}")
@Value("${author.age}")

也可以直接写在 application.properties 中(不建议这么做,但如果是全局变量提倡这种方法),当写在此文件中时,不需要指明资源文件路劲,只需要指明前缀即可。

@ImportResource 将外部的配置文件加载到程序中来。
如果要让编写的 Spring 配置文件生效,如 beans.xml,可以使用    @ImportResource 注解,将配置文件导入进来。

代码演示:
Student 类
  @Getter
    @Setter
    public class Student {

        private String name;

        private String sex;

        private String phone;
    }

rookie.xml 文件
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans              http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean id="student" class="com.rookie.model.Student">
            <property name="name" value="jack"/>
            <property name="sex" value="男人"/>
            <property name="phone" value="132659896254"/>
        </bean>
    </beans>

启动类
    @RestController
    @SpringBootApplication
    @ImportResource(locations = "classpath:rookie.xml")
    public class ConfigFileDemoApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigFileDemoApplication.class, args);
        }

        @Autowired
        private Student student;

        @GetMapping("/student")
        public String getStudent(){

            return "姓名:"+student.getName()+"==========="+"性别:"+student.getSex()+"==========="+"手机号:"+student.getPhone();
        }
    }
@ImportResource 将外部的配置文件加载到程序中来。
如果要让编写的 Spring 配置文件生效,如 beans.xml,可以使用    @ImportResource 注解,将配置文件导入进来。

代码演示:
Student 类
  @Getter
    @Setter
    public class Student {

        private String name;

        private String sex;

        private String phone;
    }

rookie.xml 文件
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans              http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean id="student" class="com.rookie.model.Student">
            <property name="name" value="jack"/>
            <property name="sex" value="男人"/>
            <property name="phone" value="132659896254"/>
        </bean>
    </beans>

启动类
    @RestController
    @SpringBootApplication
    @ImportResource(locations = "classpath:rookie.xml")
    public class ConfigFileDemoApplication {

        public static void main(String[] args) {
            SpringApplication.run(ConfigFileDemoApplication.class, args);
        }

        @Autowired
        private Student student;

        @GetMapping("/student")
        public String getStudent(){

            return "姓名:"+student.getName()+"==========="+"性别:"+student.getSex()+"==========="+"手机号:"+student.getPhone();
        }
    }