Spring Rest ErrorHandling @ControllerAdvice / @Valid

我在REST控制器中一起使用@ControllerAdvice@Valid注释时遇到了麻烦。

我有一个rest控制器声明如下:

@Controller public class RestExample { ... /** * user1passwordNameSurname * curl -d "@restAddRequest.xml" -H "Content-Type:text/xml" http://localhost:8080/SpringExamples/servlets/rest/add */ @RequestMapping(value="rest/add", method=RequestMethod.POST) public @ResponseBody String add(@Valid @RequestBody XmlRequestUser xmlUser) { User user = new User(); user.setUsername(xmlUser.getUsername()); user.setPassword(xmlUser.getPassword()); user.setName(xmlUser.getName()); user.setSurname(xmlUser.getSurname()); // add user to the database StaticData.users.put(xmlUser.getUsername(), user); LOG.info("added user " + xmlUser.getUsername()); return "added user " + user.getUsername(); } } 

还有一个ErrorHandler类:

 @ControllerAdvice public class RestErrorHandler extends ResponseEntityExceptionHandler { private static Logger LOG = Logger.getLogger(RestErrorHandler.class); @ExceptionHandler(RuntimeException.class) public ResponseEntity handleException(final RuntimeException e, WebRequest request) { LOG.error(e); String bodyOfResponse = e.getMessage(); return handleExceptionInternal(e, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request); } } 

问题是,如果我在方法RestExample.add中添加“throw new RuntimeException” ,则RestErrorHandler类会正确处理exception。

但是,当向控制器curl无效请求时, RestErrorHandler不会捕获validation器抛出的exception,并且我收到400 BadRequest响应。 (对于无效请求,我指的是未指定用户名的xml请求)

请注意, XmlRequestUser类是由插件maven-jaxb2-plugin + krasa-jaxb-tools (pom.xml)自动生成的:

  org.jvnet.jaxb2.maven2 maven-jaxb2-plugin    generate     src/main/xsd  *.xsd   -XJsr303Annotations -XJsr303Annotations:targetNamespace=http://www.foo.com/bar    com.github.krasa krasa-jaxb-tools ${krasa-jaxb-tools.version}     

生成的类在Username和Password字段上正确显示@NotNull Annotation。

我的context.xml非常简单,只包含一个控制器扫描程序并启用mvc:annotation-driven

   

有人知道如何在REST控制器中一起使用@ControllerAdvice和@Valid注释吗?

提前致谢。 安东尼奥

你是在正确的轨道上,但你需要覆盖handleMethodArgumentNotValid()而不是handleException()方法,例如

 @ControllerAdvice public class RestErrorHandler extends ResponseEntityExceptionHandler { @Override protected ResponseEntity handleMethodArgumentNotValid( MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { LOG.error(e); String bodyOfResponse = e.getMessage(); return new ResponseEntity(errorMessage, headers, status); } } 

从MethodArgumentNotValidException的JavaDoc:

对使用@Valid注释的参数进行validation失败时抛出的exception。

换句话说,validation失败时抛出MethodArgumentNotValidException 。 它由ResponseEntityExceptionHandler提供的handleMethodArgumentNotValid()方法ResponseEntityExceptionHandler ,如果您想要自定义实现,则需要覆盖该方法。

除此之外,我还有另一个关于递归validation的问题。

生成的类在其他XmlElements上缺少@valid注释。

造成这种情况的原因与我错误地使用命名空间的事实有关:

插件配置为使用特定的命名空间

 -XJsr303Annotations:targetNamespace=http://www.foo.com/bar 

所以XSD需要将其作为目标命名空间(例如):

               

善意的问候Antonio