Spring boot配置绑定和配置属性校验的方式详解

以下是关于“Spring boot配置绑定和配置属性校验的方式详解”的完整攻略,包含两个示例说明。

Spring boot配置绑定和配置属性校验的方式详解

背景

在开发 Spring Boot 应用时,我们经常需要配置一些参数,比如数据库连接信息、服务端口等等。而在应用部署时,这些参数也需要灵活地根据不同的环境进行配置,比如开发环境、测试环境、生产环境等等。因此,Spring Boot 提供了一组配置绑定和配置属性校验的方式,来帮助我们方便地处理这些问题。

配置绑定

Spring Boot 提供了多种方式来实现配置绑定,这里介绍其中比较常用的两种方式。

1. 使用 @ConfigurationProperties 注解

@ConfigurationProperties 注解可以将配置文件中的属性与 Java 类的属性进行绑定,使用起来比较简单。具体步骤如下:

  1. 定义一个配置类,使用 @ConfigurationProperties 注解指定要绑定的属性前缀。
@ConfigurationProperties(prefix = "my")
public class MyConfig {
    private String name;
    private String description;
    // ... 其他属性的定义及其 getter/setter 方法
}
  1. 在配置文件 application.yml 或 application.properties 中设置属性值。
my:
  name: My Application
  description: This is a demo application.
  1. 在 Spring Boot 应用中注入该配置类即可。
@RestController
public class MyController {
    private MyConfig myConfig;

    public MyController(MyConfig myConfig) {
        this.myConfig = myConfig;
    }

    @GetMapping("/my-config")
    public MyConfig getConfig() {
        return myConfig;
    }
}

这样,我们就可以在 /my-config 接口中获取到应用配置信息了。

2. 使用 @Value 注解

@Value 注解同样可以将配置文件中的属性与 Java 类的属性进行绑定,但相对来说使用起来稍微麻烦一些。具体步骤如下:

  1. 在 Java 类中使用 @Value 注解,指定要绑定的属性及其默认值。
public class MyConfig {
    @Value("${my.name:My Application}")
    private String name;

    @Value("${my.description:This is a demo application.}")
    private String description;

    // ... 其他属性的定义及其 getter/setter 方法
}
  1. 在配置文件中设置属性值,如果没有设置,则使用默认值。
my:
  description: This is a demo application.
  1. 在 Spring Boot 应用中注入该配置类即可。
@RestController
public class MyController {
    private MyConfig myConfig;

    public MyController(MyConfig myConfig) {
        this.myConfig = myConfig;
    }

    @GetMapping("/my-config")
    public MyConfig getConfig() {
        return myConfig;
    }
}

属性校验

在应用开发过程中,我们经常需要对属性进行校验,以保证应用逻辑的正确性和安全性。Spring Boot 可以通过 Hibernate Validator 库来实现属性校验。

1. 使用注解进行校验

我们可以在实体类的属性上,使用注解来指定该属性的校验规则,Spring Boot 将会自动对该属性进行校验。具体步骤如下:

  1. 引入 Hibernate Validator 依赖。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  1. 定义一个实体类,并使用注解指定属性的校验规则。
public class User {
    @NotBlank(message = "用户名不能为空")
    private String username;

    @Size(min = 6, max = 32, message = "密码长度必须为 6 ~ 32 个字符")
    private String password;

    @Email(message = "邮箱格式不正确")
    private String email;

    // ... 其他属性的定义及其 getter/setter 方法
}
  1. 在接口中使用 @Validated 注解,并添加 BindingResult 参数,Spring Boot 将会自动对实体类进行校验,并将错误信息保存在 BindingResult 中。
@RestController
@RequestMapping("/users")
@Validated
public class UserController {
    @PostMapping
    public ResponseEntity<?> createUser(@RequestBody @Valid User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseEntity.badRequest().body(bindingResult.getAllErrors());
        }
        // ... 创建用户逻辑
    }
}

2. 自定义校验器

除了使用注解进行校验之外,我们还可以自定义校验器,来实现更加复杂的校验逻辑。具体步骤如下:

  1. 定义一个校验器。校验器需要实现 ConstraintValidator 接口,并重写 initialize 和 isValid 两个方法。
public class MyValidator implements ConstraintValidator<MyAnnotation, String> {
    private String[] values;

    @Override
    public void initialize(MyAnnotation annotation) {
        values = annotation.value();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return Arrays.asList(values).contains(value);
    }
}
  1. 定义一个注解,并使用 @Constraint 注解指定关联的校验器。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyValidator.class)
public @interface MyAnnotation {
    String message() default "参数不正确";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String[] value();
}
  1. 在实体类的属性上使用自定义注解,即可实现自定义校验器的功能。
public class MyRequest {
    @MyAnnotation(value = {"A", "B", "C"}, message = "类型必须为 A/B/C")
    private String type;

    // ... 其他属性的定义及其 getter/setter 方法
}

这样,在使用 @Validated 校验实体类时,自定义的校验器也将被自动地执行。

示例说明

这里给出两个示例说明,分别演示了如何使用 @ConfigurationProperties 进行配置绑定,以及如何自定义校验器。

示例1:使用 @ConfigurationProperties 进行配置绑定

首先,我们创建一个 MyConfig 类,在该类中定义了两个属性 name 和 description,并使用 @ConfigurationProperties 注解将其与配置文件中的属性进行了绑定。

@ConfigurationProperties(prefix = "my")
public class MyConfig {
    private String name;
    private String description;

    // ... 其他属性的定义及其 getter/setter 方法
}

然后,在配置文件 application.yml 中设置了 MyConfig 类的两个属性值。

my:
  name: My Application
  description: This is a demo application.

最后,在控制器中注入 MyConfig 类,并将其作为接口返回值,即可实现配置绑定的功能。

@RestController
public class MyController {
    private MyConfig myConfig;

    public MyController(MyConfig myConfig) {
        this.myConfig = myConfig;
    }

    @GetMapping("/my-config")
    public MyConfig getConfig() {
        return myConfig;
    }
}

此时,访问 /my-config 接口,即可获取到 MyConfig 类的属性值,验证了配置绑定的功能。

示例2:自定义校验器

首先,我们定义了一个 MyRequest 类,在该类中使用了自定义注解 MyAnnotation,该注解使用 MyValidator 校验器,来校验 type 属性的值是否在指定范围内。

public class MyRequest {
    @MyAnnotation(value = {"A", "B", "C"}, message = "类型必须为 A/B/C")
    private String type;

    // ... 其他属性的定义及其 getter/setter 方法
}

然后,我们实现了 MyValidator 校验器,该校验器接收一个 String 类型的值,和一个注解对象,在初始化时,将注解对象中的合法值取出来,然后在 isValid 方法中,判断当前值是否在合法值列表内,如果存在,则说明合法,返回 true,否则说明不合法,返回 false。

public class MyValidator implements ConstraintValidator<MyAnnotation, String> {
    private String[] values;

    @Override
    public void initialize(MyAnnotation annotation) {
        values = annotation.value();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return Arrays.asList(values).contains(value);
    }
}

最后,在使用 MyRequest 类进行校验时,就会自动地执行 MyValidator 校验器了,示例如下。

@RestController
@RequestMapping("/my")
@Validated
public class MyController {
    @PostMapping("/validate")
    public ResponseEntity<?> validateRequest(@RequestBody @Valid MyRequest request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseEntity.badRequest().body(bindingResult.getAllErrors());
        }
        return ResponseEntity.ok().build();
    }
}

启动应用之后,可以使用 Postman 或 curl 等命令行工具,向服务器发送如下请求。

{
  "type": "X"
}

此时,服务器将会返回 400 错误,响应体中包含了错误提示信息。

[
    {
        "codes": [
            "MyRequest.type",
            "type",
            "java.lang.String",
            "myrequest",
            "myRequest.type",
            "myRequest",
            "type"
        ],
        "arguments": [
            {
                "codes": [
                    "A",
                    "B",
                    "C"
                ],
                "arguments": null,
                "defaultMessage": null,
                "code": "A"
            }
        ],
        "defaultMessage": "参数不正确",
        "objectName": "myRequest",
        "field": "type",
        "rejectedValue": "X",
        "bindingFailure": false,
        "code": "myAnnotation"
    }
]

当 type 的值为 A、B、C 中的一个时,请求将会成功通过校验。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring boot配置绑定和配置属性校验的方式详解 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • 深入理解Java定时调度(Timer)机制

    深入理解Java定时调度(Timer)机制 什么是Java定时调度(Timer)机制? Java定时调度(Timer)机制是Java中的一个工具类,常用于在指定时间后运行代码或以固定间隔时间重复执行代码。 它通过创建一个线程来实现定时调度功能,其中的schedule()和scheduleAtFixedRate()方法提供了不同的时间调度方式。 schedul…

    Java 2023年5月20日
    00
  • java字符串的重要使用方法以及实例

    下面是关于Java字符串的重要使用方法以及实例的完整攻略。 什么是Java字符串? Java字符串是一种保存一系列字符的对象,是Java中最常用的数据类型之一。在Java中,字符串是不可变的,因此每个对字符串的操作都会产生一个新的字符串对象。字符串作为Java编程中的重要部分,我们需要了解一些重要的使用方法。 Java字符串的声明 在Java中,字符串的声明…

    Java 2023年5月26日
    00
  • Spring Security中如何获取AuthenticationManager对象

    获取AuthenticationManager对象的方法会因不同的Spring Security版本而有所不同,以下是三种常用的方法及示例: 方法一:使用@Configuration注解配置 在Spring Security配置类中添加@Bean注解并返回AuthenticationManager对象即可。 示例一:Spring Boot 1.x版本 imp…

    Java 2023年5月20日
    00
  • Java建造者模式构建复杂对象的最佳实践

    Java建造者模式是一种创建型设计模式,通过一步一步的构建复杂对象来实现构建者模式。 下面是Java建造者模式构建复杂对象的完整攻略: 步骤一:创建一个产品类 创建一个产品类,该类由多个属性组成,并提供setter和getter方法。 public class Computer { private String cpu; private String mem…

    Java 2023年5月26日
    00
  • Spring 注解

    @SpringBootApplication 申明让spring boot自动给程序进行必要的配置,这个配置等同于: @Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个配置。 @RequestMapping 提供路由信息,负责URL到Controller中的具体函数的映射。 @Respon…

    Java 2023年5月9日
    00
  • Java冒泡排序的定义与实例代码

    Java冒泡排序是一种简单的排序算法,其基本思想是通过交换相邻元素的位置来达到排序的目的。在本篇攻略中,我将详细讲解Java冒泡排序的定义与实例代码。 定义 冒泡排序是一种交换排序。它的工作原理就像把一堆泡泡按大小排序一样。具体来说,它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。重复进行直到没有任何一个数需要交换位置为止。…

    Java 2023年5月19日
    00
  • MyBatis3源码解析之如何获取数据源详解

    首先,我们需要明确一下MyBatis3是什么,它的作用是什么。MyBatis3是一个持久层框架,它的作用是将Java对象和关系型数据库之间的操作映射起来,使得我们可以通过Java对象对数据库进行简单的增、删、改、查操作,而无需编写大量的SQL语句。接下来,我将从获取数据源的角度出发,给大家讲解如何理解MyBatis3的数据源配置。 数据源配置 在MyBati…

    Java 2023年5月20日
    00
  • Gateway+Swagger2配置聚合文档方式

    下面是“Gateway+Swagger2配置聚合文档方式”的完整攻略,包含以下几个步骤: 1. 引入Swagger2依赖 在网关服务的pom.xml文件中添加Swagger2依赖: <dependency> <groupId>io.springfox</groupId> <artifactId>springfo…

    Java 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部