SpringBoot参数校验与国际化使用教程

作者:weisen 时间:2021-11-13 15:52:21 

一、参数校验

springboot 使用校验框架validation校验方法的入参

SpringBoot的Web组件内部集成了hibernate-validator,所以我们这里并不需要额外的为验证再导入其他的包。

1、bean 中添加标签

标签需要加在属性上,@NotEmpty标签String的参数不能为空


@Data
public class DemoDto {

@NotEmpty(message = "名称不能为空")
private String name;

@Length(min = 5, max = 25, message = "key的长度为5-25")
private String key;

@Pattern(regexp = "[012]", message = "无效的状态标志")
private String state;

}

2、Controller中开启验证

在Controller 中 请求参数上添加@Validated 标签开启验证


@RequestMapping("test")
public String test(@Valid @RequestBody DemoDto dto){
System.out.println("test....................");
return "test.........................";
}

测试返回结果

{
    "timestamp": "2020-01-14 13:30:03",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "Length.demoDto.key",
                "Length.key",
                "Length.java.lang.String",
                "Length"
            ],
            "arguments": [
                {
                    "codes": [
                        "demoDto.key",
                        "key"
                    ],
                    "arguments": null,
                    "defaultMessage": "key",
                    "code": "key"
                },
                25,
                5
            ],
            "defaultMessage": "key的长度为5-25",
            "objectName": "demoDto",
            "field": "key",
            "rejectedValue": "11",
            "bindingFailure": false,
            "code": "Length"
        },
        {...},
        {...}
    ],
    "message": "Validation failed for object='demoDto'. Error count: 3",
    "path": "/test"
}

返回的错误信息比较乱,需要统一整理,这个时候可以使用全局异常处理的方法

3、异常处理,捕获错误信息

当验证不通过时会抛异常出来。在异常处理器中捕获异常信息(因为验证不通过的项可能是多个所以统一捕获处理),并抛给前端。(此处是前后端分离开发)


@RequestMapping("test")
public ResultBean test(@Valid @RequestBody DemoDto dto){
System.out.println("test....................");
return new ResultBean("test.........................");
}

这里统一返回一个自定义的ResultBean类型


@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(value = MethodArgumentNotValidException.class)
public ResultBean methodArgumentNotValid(HttpServletRequest req, MethodArgumentNotValidException ex) {
ResultBean result = ResultBean.FAIL;
List<ObjectError> errors =ex.getBindingResult().getAllErrors();
StringBuffer errorMsg=new StringBuffer();
errors.stream().forEach(x -> errorMsg.append(x.getDefaultMessage()).append(";"));
log.error("---MethodArgumentNotValidException Handler--- ERROR: {}", errorMsg.toString());
result.setMsg(errorMsg.toString());
return result;
}
}

此时的返回结果为:

{
    "code": 500,
    "msg": "无效的状态标志;key的长度为5-25;名称不能为空;",
    "content": null
}

二、分组校验

有时候需要在不同的方法中对同一个bean中的参数进行校验

1、在dto中添加groups


@Data
public class DemoDto {
public interface Default {
}
public interface Update {
}
@NotEmpty(message = "名称不能为空")
private String name;
@Length(min = 5, max = 25, message = "key的长度为5-25" ,groups = Default.class )
private String key;
@Pattern(regexp = "[012]", message = "无效的状态标志",groups = {Default.class,Update.class} )
private String state;
}

2、在controller中需要用到@Validated来校验


@RequestMapping("test2")
public String test2(@Validated(value = DemoDto.Default.class) @RequestBody DemoDto dto){
System.out.println("test....................");
return "test.........................";
}

@RequestMapping("test4")
public String test4(@Validated(value = {DemoDto.Default.class,DemoDto.Update.class}) @RequestBody DemoDto dto){
System.out.println("test....................");
return "test.........................";
}

三、国际化返回配置文件的信息

1. 在Resource下添加properties文件

SpringBoot参数校验与国际化使用教程

文件中添加需要打印的消息,如:


demo.key.null=demo的key不能为空
start.ge.end = 开始日期{0}必须小于结束日期{1}!
demo.key.length=demo的key长度不正确

2. 在application.yml中添加配置


spring:
messages:
encoding: UTF-8
basename: message/messages_zh

3. 使用方法

在类中直接注入,即可使用


@Autowired
private MessageSource messageSource;

@RequestMapping("getMessageByKey")
public ResultBean getMessageByKey(@Valid @RequestBody DemoDto dto){
String key = dto.getKey();
String [] param = {"2019-8-8", "2019-9-9"};
return new ResultBean(messageSource.getMessage(key, param, Locale.CHINA));
}

测试调用和返回结果,返回的数据和预期相符合

SpringBoot参数校验与国际化使用教程

三、国际化参数校验

根据上面的修改

1、bean 中添加标签

标签需要加在属性上,@NotEmpty标签String的参数不能为空


@Data
public class DemoDto {

@NotEmpty(message = "{demo.key.null}")
@Length(min = 5, max = 25, message = "{demo.key.length}")
private String key;
}

2、添加上ValidationMessages文件

国际化配置文件必须放在classpath的根目录下,即src/java/resources的根目录下。

国际化配置文件必须以ValidationMessages开头,比如ValidationMessages.properties 或者 ValidationMessages_en.properties。

在/resources的根目录下添加上ValidationMessages.properties文件


demo.key.null=demo的key不能为空,这里是validationMessage
demo.key.length=demo的key长度不正确

3、返回结果

{
    "code": 500,
    "msg": "demo的key不能为空,这里是validationMessage;",
    "content": null
}

自定义properties文件

SpringBoot 国际化验证 @Validated 的 message 国际化资源文件默认必须放在 resources/ValidationMessages.properties 中。

现在我想把资源文件放到 resources/message/messages_zh.properties 中

若要自定义文件位置或名称则需要重写WebMvcConfigurerAdapter 的 getValidator 方法,但WebMvcConfigurerAdapter在springboot2中已经废弃了,可以改为使用WebMvcConfigurationSupport

在一的基础上修改:


@Configuration
public class ValidatorConfiguration extends WebMvcConfigurationSupport {
@Autowired
private MessageSource messageSource;

@Override
public Validator getValidator() {
 return validator();
}

@Bean
public Validator validator() {
 LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
 validator.setValidationMessageSource(messageSource);
 return validator;
}
}

最后得到结果为:

{
    "code": 500,
    "msg": "demo的key不能为空ID:{0};",
    "content": null
}

参考文章:

spring boot国际化——MessageSource的使用

来源:https://www.jianshu.com/p/46eda1f96abe

标签:参数,校验,国际化
0
投稿

猜你喜欢

  • Android编程中避免内存泄露的方法总结

    2023-07-27 19:32:50
  • 简单了解4种分布式session解决方案

    2023-08-09 11:45:49
  • Spring Boot常用注解(经典干货)

    2023-11-24 22:29:10
  • 详解Spring Boot 定制HTTP消息转换器

    2023-11-24 20:20:51
  • C语言文件操作函数大全(超详细)

    2023-07-15 06:20:42
  • java自带的MessageDigest实现文本的md5加密算法

    2023-10-08 03:35:29
  • JAVA实现经典扫雷游戏的示例代码

    2022-01-26 04:20:18
  • springboot如何使用AOP做访问请求日志

    2023-11-11 10:12:19
  • java如何获得redis所有的key-value

    2022-03-13 12:22:14
  • Java以命令模式设计模式

    2023-11-24 21:27:52
  • Spring Bean生命周期之BeanDefinition的合并过程详解

    2023-11-29 02:50:35
  • Flutter基于Dart Unwrapping Multiple Optional小技巧

    2023-07-05 11:44:19
  • Java如何将字符串String转换为整型Int

    2023-11-10 21:40:19
  • 基于Tomcat7、Java、WebSocket的服务器推送聊天室实例

    2023-11-25 23:35:34
  • springmvc 分页查询的简单实现示例代码

    2022-01-09 11:08:22
  • Java基础之Thymeleaf的简单使用

    2023-08-24 19:00:22
  • 一文梳理Java 8后的新功能

    2023-07-13 07:41:43
  • JAVA中实现原生的 socket 通信机制原理

    2021-08-08 03:06:01
  • 详解spring-boot集成elasticsearch及其简单应用

    2021-08-26 01:09:58
  • MyBatis找不到mapper文件的实现

    2023-12-15 09:22:11
  • asp之家 软件编程 m.aspxhome.com