乐趣区

关于spring:Springvalidator国际化

依赖

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.0</version>
</parent>

...

<!-- ^api validation -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.6.Final</version>
</dependency>
<!-- api validation$ -->

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<String, String> VALIDATION_ANNATATION_DEFAULT_MESSAGES =
            new HashMap<String, String>(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

国际化资源文件

文件:

  • 默认: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 = 18, message = "{age}") @Max(value = 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

  • 配置环境变量
    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
退出移动版