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
编辑器关于properties编码转换
在IDEA的Setting -> Editor -> File Encodings,勾选Transarent native-to-asiic conversion
最好编码全部转为UTF-8
Spring+validator国际化
文章图片

国际化资源文件
文件:
  • 默认: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注解,这样里面的namemail才能被校验
  • 所有支持的参数校验注解在javax.validation.constraints包下
测试REST
  • 【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

    推荐阅读