使用Spring Boot,我有一个接口,其中包含声明为
的方法@GET
@Path("/{name}")
ProductResponse find( @Size(min = 3) @PathParam("name") String name) throws BusinessException;
和一个用@Validated注释的Rest控制器,实现上述接口 控制器还实现了方法
@ExceptionHandler(value = { ConstraintViolationException.class })
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleResourceNotFoundException(ConstraintViolationException e) {
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
StringBuilder strBuilder = new StringBuilder();
for (ConstraintViolation<?> violation : violations ) {
strBuilder.append(violation.getMessage() + "\n");
}
return strBuilder.toString();
}
@configuration注释类还包括方法
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
这适用于所有请求,但问题是当请求包含不符合约束的名称时,不会调用方法handleResourceNotFoundException。
然而,在控制台中我看到了ConstraintViolationException
[some omitted]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
Caused by: javax.validation.ConstraintViolationException: null
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:136) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.ncr.nep.sdk.service.aspect.PayloadValidationInterceptor.invoke(PayloadValidationInterceptor.java:103) ~[nep-sdk-service-1.19.0-GA.jar:1.19.0-GA]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.ncr.nep.sdk.service.aspect.ExceptionInterceptor.invoke(ExceptionInterceptor.java:41) ~[nep-sdk-service-1.19.0-GA.jar:1.19.0-GA]
... 95 common frames omitted
那么为什么没有调用处理方法并且返回500作为响应代码?我错过了什么?
答案 0 :(得分:1)
您正在使用JAX-RS(@GET
,@Path
,@PathParam
,...)和Spring @ExceptionHandler
。我的猜测是,这种组合不起作用。所以要么你应该使用Spring重写你的控制器:
@GetMapping("/{name}") // Replacement of @Path and @GET
// @PathVariable replaces @PathParam
ProductResponse find( @Size(min = 3) @PathVariable("name") String name) throws BusinessException {
// ...
}
请注意,并非所有Spring注释都适用于接口,因此您可能需要将它们移动到实际实现中。
或者,您可以使用JAX-RS的ExceptionMapper
:
@Component
public class ConstraintViolationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {
@Override
public Response toResponse(ConstraintViolationException e) {
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
StringBuilder strBuilder = new StringBuilder();
for (ConstraintViolation<?> violation : violations ) {
strBuilder.append(violation.getMessage() + "\n");
}
return Response.status(Response.Status.BAD_REQUEST).entity(strBuilder.toString()).build();
}
}
在这种情况下,如果您使用的是Jersey,请务必在ResourceConfig
实施中注册异常映射器。