ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

记@NotEmpty不生效问题解决

2022-03-04 10:32:14  阅读:814  来源: 互联网

标签:String NotEmpty test 为空 生效 解决 message desc


  问题:Controller层添加@NotEmpty或者@NotNull不生效,像下面这样:
1 @ApiOperation(value = "测试")
2 @GetMapping("/test")
3 public String test(@NotEmpty(message = "desc不能为空") String name,
4                                @NotNull(message = "age不能为空") Long age,
5                                @NotEmpty(message = "desc不能为空") String desc) {
6     return "test";
7 }
    但是这样使用实体类,里面的属性使用@NotEmpty就是生效的:
 1 @ApiOperation(value = "测试")
 2 @PostMapping("/test")
 3 public String test(@RequestBody @Valid NoticeParam noticeParam) {
 4     return "test";
 5 }
 6 
 7 @ApiModel(description = "测试")
 8 @Data
 9 public class NoticeParam {
10     @NotEmpty(message = "name不能为空") 
11     private String name;
12     
13     @NotNull(message = "desc不能为空") 
14     private Long age;
15     
16     @NotEmpty(message = "desc不能为空") 
17     private String desc;
18 }
排查过程:     1.检查两者的区别,发现参数前面有个@Valid,于是在参数前面同样加了个@Valid
@ApiOperation(value = "测试")
@GetMapping("/test")
public String test(@Valid @NotEmpty(message = "desc不能为空") String name,
                               @NotNull(message = "age不能为空") Long age,
                               @NotEmpty(message = "desc不能为空") String desc) {
    return "test";
}
  postman测试: name,age,desc都没传,但是仍然返回了成功。说明@Valid在这里不生效。

  2.将@NotEmpty换成了@RequestParam,@RequestParam的源码如下,可以看到required是默认为true的。

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";

@AliasFor(</span>"value"<span style="color: #000000;">)
String name() </span><span style="color: #0000ff;">default</span> ""<span style="color: #000000;">;

</span><span style="color: #0000ff;">boolean</span> required() <span style="color: #0000ff;">default</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;

String defaultValue() </span><span style="color: #0000ff;">default</span> "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"<span style="color: #000000;">;

}

    但是加上了@RequestParam之后,虽然是被拦截了,但是没有将错误信息抛出来:

  

  只是抛出了系统的默认错误:

 

 

  而且@RequestParam不够灵活,没办法自定义抛出错误信息。所以还是从@NotEmpty下手。

 

  3.从网上找资料,发现使用@Validated标记Controller层,然后再在参数中添加@NotEmpty,就可以抛出错误:
@Api(tags = "通知接口")
@RestController
@RequestMapping("/api/notice")
@Validated
public class TestApi {
@ApiOperation(value </span>= "测试"<span style="color: #000000;">)
@GetMapping(</span>"/test"<span style="color: #000000;">)
</span><span style="color: #0000ff;">public</span> String test(@NotEmpty(message = "name不能为空"<span style="color: #000000;">)  String name,
                 @NotNull(message </span>= "age不能为空"<span style="color: #000000;">) Long age,
                 @NotEmpty(message </span>= "desc不能为空"<span style="color: #000000;">) String desc) {
    </span><span style="color: #0000ff;">return</span> "test"<span style="color: #000000;">;
}

}

  

  测试之后控制台打印出了错误

 

 

  但是在返回参数中,并未返回最终错误信息:

 

 

  抛出来的错误并不是我们添加的错误信息,而是系统的默认错误。很明显,系统中有对这种异常专门的处理,但是漏掉了ConstraintViolationException这种异常的错误。我通过打印日志排查,找到了处理系统错误的代码:
@ExceptionHandler
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public BaseResult<?> exceptionHandler(Exception ex, HttpServletRequest request) {
    log.error("", ex);
    if (StringUtils.containsIgnoreCase(ExceptionUtils.getRootCauseMessage(ex), "Broken pipe")) {
        return null;
    }
    //处理异常
    ErrorConstants error = ErrorHandler.handle(ex);
    BaseResult<?> res = BaseResult.failure(error.getCode(), error.getMsg());
    logResponse(res);
    return res;
}

public class ErrorHandler {

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> ErrorConstants handle(Throwable e) {
    </span><span style="color: #008000;">//</span><span style="color: #008000;">UNKNOWN_ERROR("未知错误", 101,  "抱歉,我们遇到一点问题,请您稍后再试。"),</span>
    ErrorConstants error =<span style="color: #000000;"> ErrorConstants.UNKNOWN_ERROR;
    </span><span style="color: #008000;">//</span><span style="color: #008000;">异常处理判断,项目代码不便展示</span>

...
//处理ConstraintViolationException异常时,前面的if都没进去,默认给了系统错误。
return error;
}

}

    处理方式:   添加一个@ExceptionHandler针对ConstraintViolationException的处理,代码如下:
@ExceptionHandler({ConstraintViolationException.class})
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public BaseResult<?> bindExceptionHandler(ConstraintViolationException ex) {
    log.error("", ex);
    String message = ErrorConstants.ILLEGAL_PARAM.getMsg();
    //取出@NotEmpty后面message的自定义错误信息
    Optional<ConstraintViolation<?>> aa = ex.getConstraintViolations().stream().findFirst();
    if (aa.isPresent()) {
        message = aa.get().getMessage();
    }
    //赋值并抛出
    BaseResult<?> res = BaseResult.failure(ErrorConstants.ILLEGAL_PARAM.getCode(), message);
    logResponse(res);
    return res;
}
     效果:  

 

  结论:

  1.@ExceptionHandler用于处理全局异常的,也可以处理单独的异常类。   2.上面在Controller类上面使用@Validated是生效的,但是使用@Valid是不生效的,原因还不清楚。   3.@RequestParam未直接抛出对应异常,和@NotEmpty处理方式一样,可以加个@ExceptionHandler({MissingServletRequestParameterException.class})可以抛出异常。如下
org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present

 


 

标签:String,NotEmpty,test,为空,生效,解决,message,desc
来源: https://www.cnblogs.com/catxx/p/15963200.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有