问题: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("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
但是加上了@RequestParam之后,虽然是被拦截了,但是没有将错误信息抛出来:
只是抛出了系统的默认错误:
而且@RequestParam不够灵活,没办法自定义抛出错误信息。所以还是从@NotEmpty下手。
3.从网上找资料,发现使用@Validated标记Controller层,然后再在参数中添加@NotEmpty,就可以抛出错误:
@Api(tags = "通知接口")
@RestController
@RequestMapping("/api/notice")
@Validated
public class TestApi {
@ApiOperation(value = "测试")
@GetMapping("/test")
public String test(@NotEmpty(message = "name不能为空") String name,
@NotNull(message = "age不能为空") Long age,
@NotEmpty(message = "desc不能为空") String desc) {
return "test";
}
}
测试之后控制台打印出了错误
但是在返回参数中,并未返回最终错误信息:
抛出来的错误并不是我们添加的错误信息,而是系统的默认错误。很明显,系统中有对这种异常专门的处理,但是漏掉了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 {
public static ErrorConstants handle(Throwable e) {
//UNKNOWN_ERROR("未知错误", 101, "抱歉,我们遇到一点问题,请您稍后再试。"),
ErrorConstants error = ErrorConstants.UNKNOWN_ERROR;
//异常处理判断,项目代码不便展示
...
//处理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
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/158120.html