Chi*_*hak 3 java validation spring json
我的配置文件中有一些值,它应该是 JSON(它将作为字符串加载)。
我希望 Spring 在注入之前验证该值确实是有效的 JSON,否则会抛出错误。
我按如下方式注入它:
@Value("${source.SomeJsonString}")
private String someJsonString;
Run Code Online (Sandbox Code Playgroud)
我看到了以下内容:How to make simple propertyvalidation when using Spring @Value
但是,由于我有多个应该注入的类source.SomeJsonString
,所以我不想为每个类创建一个setter,并一次又一次地编写验证。
有没有办法只写一次验证器?
我考虑过创建注释(Spring validate string value is a JSON),但似乎注释的值@Value
无法验证。
还有其他办法吗?
Spring 外部化配置可以使用 JSR 303 Bean Validation API 进行验证。但它需要Spring 类型安全的配置属性而不是@Value("${property}")
.
将 Hibernate Validator 依赖项添加到build.gradle
implementation 'org.hibernate.validator:hibernate-validator'
Run Code Online (Sandbox Code Playgroud)
类型安全配置属性必须使用自定义注释进行@Validated
注释someJsonString
@ValidJsonConstraint
@Component
@ConfigurationProperties("source")
@Validated
public class SourceProperties {
@ValidJsonConstraint
private String someJsonString;
public String getSomeJsonString() {
return someJsonString;
}
public void setSomeJsonString(String someJsonString) {
this.someJsonString = someJsonString;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将属性注入到所有必需的服务中,因此验证代码不会重复
@Autowired
private SourceProperties sourceProperties;
Run Code Online (Sandbox Code Playgroud)
是时候创建自定义注释了
@Documented
@Constraint(validatedBy = ValidJsonValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidJsonConstraint {
String message() default "Invalid JSON";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Run Code Online (Sandbox Code Playgroud)
以及一个验证器,用于验证使用自定义注释注释的字段
public class ValidJsonValidator implements ConstraintValidator<ValidJsonConstraint, String> {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void initialize(ValidJsonConstraint constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
try {
objectMapper.readTree(value);
return true;
} catch (JsonProcessingException e) {
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当application.properties中的值source.someJsonString
是有效的 JSON时
source.someJsonString={"test":"qwe"}
Run Code Online (Sandbox Code Playgroud)
应用程序成功启动。
当 JSON 无效时
source.someJsonString=qwe
Run Code Online (Sandbox Code Playgroud)
应用程序无法启动,出现以下异常
***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'source' to intellectsoft.afgruppen.shiftschedule.SourceProperties failed:
Property: source.someJsonString
Value: qwe
Origin: class path resource [application.properties]:26:23
Reason: Invalid JSON
Action:
Update your application's configuration
Run Code Online (Sandbox Code Playgroud)
另外,如果没有 JSR 303 Bean Validation API,也可以更容易地实现同样的效果。
创建自定义验证组件
@Component
public class JsonValidator {
private final ObjectMapper objectMapper = new ObjectMapper();
public boolean isValid(String value) {
try {
objectMapper.readTree(value);
return true;
} catch (JsonProcessingException e) {
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
注入验证器并在属性设置器中执行验证
@Component
@ConfigurationProperties("source")
public class SourceProperties {
private final JsonValidator jsonValidator;
private String someJsonString;
public SourceProperties(JsonValidator jsonValidator) {
this.jsonValidator = jsonValidator;
}
public String getSomeJsonString() {
return someJsonString;
}
public void setSomeJsonString(String someJsonString) {
if (!jsonValidator.isValid(someJsonString)) {
throw new IllegalArgumentException(someJsonString + " is not a valid JSON");
}
this.someJsonString = someJsonString;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2302 次 |
最近记录: |