SpringBoot参数校验和国际化使用

一、参数校验

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文件

image.png

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

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));
    }

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


image.png

三、国际化参数校验

根据上面的修改

  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;
}
  1. 添加上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长度不正确
  1. 返回结果
{
    "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的使用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容