Spring+validator国际化
依赖
pom.xml
:
org.springframework.boot
spring-boot-starter-parent
2.4.0
...
org.springframework.boot
spring-boot-starter-validation
javax.validation
validation-api
2.0.1.Final
org.hibernate
hibernate-validator
6.1.6.Final
Spring配置
ValidationConfig.class
:import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import javax.validation.Validator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* 自动处理参数校验的扩展信息
*/
@Configuration
public class ValidationConfig {@Bean
public Validator validator() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setMessageInterpolator(new MessageInterpolator());
return localValidatorFactoryBean;
}private class MessageInterpolator extends ResourceBundleMessageInterpolator {
@Override
public String interpolate(String message, Context context, Locale locale) {
// 获取注解类型
String annotationTypeName = context.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName();
// 根据注解类型获取自定义的消息Code
String annotationDefaultMessageCode = VALIDATION_ANNATATION_DEFAULT_MESSAGES.get(annotationTypeName);
if (null != annotationDefaultMessageCode && !message.startsWith("javax.validation")
&& !message.startsWith("org.hibernate.validator.constraints")) {
// 如果注解上指定的message不是默认的javax.validation或者org.hibernate.validator等开头的情况,
// 则需要将自定义的消息Code拼装到原message的后面;
message += "{" + annotationDefaultMessageCode + "}";
}return super.interpolate(message, context, locale);
}
}private static final Map VALIDATION_ANNATATION_DEFAULT_MESSAGES =
new HashMap(20) {{
put("Min", "validation.message.min");
put("Max", "validation.message.max");
put("NotNull", "validation.message.notNull");
put("NotBlank", "validation.message.notBlank");
put("Size", "validation.message.size");
}};
}
Notes:
- 注意 Validator 的包路径是
javax.validation.Validator
在IDEA的Setting -> Editor -> File Encodings,勾选
Transarent native-to-asiic conversion
最好编码全部转为UTF-8
文章图片
国际化资源文件
文件:
- 默认:
resources/ValidationMessages.properties
- 英文:
resources/ValidationMessages_en.properties
- 内容:
validation.message.min=不能小于{value} validation.message.max=不能大于{value} validation.message.notNull=不能为空 validation.message.notBlank=不能为空 validation.message.size=长度必须在{min}和{max}之间age=年龄 mail=邮箱
ValidatorMvc.class
:import lombok.Data;
import lombok.ToString;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* @author chad
* @date 2021/10/26 18:13
* @since
*/
@RestController
@RequestMapping("validation")
@Validated
public class ValidatorMvc {
@Validated
@Valid
@PostMapping("/hello")
public String hello(
@Min(value = https://www.it610.com/article/18, message ="{age}") @Max(value = https://www.it610.com/article/60, message ="{age}") @RequestParam Integer age
, @RequestBody @Valid User user
) {
System.out.println("user ==> " + user.toString() + ", age ==> " + age);
return "Hello " + user.name;
}@Data
@ToString
public static class User {
/**
* 姓名
*/
@Size(min = 2, max = 10, message = "{name}")
private String name;
@NotBlank(message = "{mail}")
private String mail;
}
}
Notes:
- 类上的
@Validated
注解一定要加,这样参数age
才能被校验 @RequestBody
一定要带@Valid
注解,这样里面的name
和mail
才能被校验- 所有支持的参数校验注解在
javax.validation.constraints
包下
- 【Spring+validator国际化】配置环境变量
src/test/rest/http-client.env.json
:
### 测试 age 小于18 ###### res ==> age must great or equals 18 POST {{host}}/validation/hello?age=17 content-type: application/json{ "name": "zhangsan", "mail": "test@mail.com" }### 测试 age 大于 60 ###### res ==> age must less or equals 60 POST {{host}}/validation/hello?age=61 content-type: application/json{ "name": "zhangsan", "mail": "test@mail.com" }### 测试 mail 为空-空字符串 ###### res ==> mail cannot empty POST {{host}}/validation/hello?age=18 content-type: application/json{ "name": "zhangsan", "mail": "" }### 测试 mail 为空-null ###### res ==> mail cannot empty POST {{host}}/validation/hello?age=18 content-type: application/json{ "name": "zhangsan", "mail": null }### 测试 name 小于2位 ###### res ==> name length must between 2 and 10 POST {{host}}/validation/hello?age=18 content-type: application/json{ "name": "0", "mail": "test@mail.com" }### 测试 name 大于10位 ###### res ==> name length must between 2 and 10 POST {{host}}/validation/hello?age=18 content-type: application/json{ "name": "01234567890", "mail": "test@mail.com" }### 成功 ###### res ==> Hello ZhangSan POST {{host}}/validation/hello?age=18 content-type: application/json{ "name": "ZhangSan", "mail": "test@mail.com" }
- Gitee
推荐阅读
- 带有Hilt的Android上的依赖注入
- Vue源码分析—响应式原理(二)
- 依赖注入模块
- IDEA使用Maven管理项目包,缺少pom文件中引入的依赖包
- SpringBoot解决Shiro导致依赖注入的bean事务失效问题
- spring5源码系列--循环依赖|spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖
- SpringBean单例情况下解决循环依赖的原理
- iOS国际化支持
- Android|Android Room 的坑
- Springboot项目的搭建教程(分离出common父依赖)