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
从MethodArgumentNotValidException的JavaDoc:
对使用@Valid注释的参数进行validation失败时抛出的exception。
换句话说,validation失败时抛出MethodArgumentNotValidException
。 它由ResponseEntityExceptionHandler
提供的handleMethodArgumentNotValid()
方法ResponseEntityExceptionHandler
,如果您想要自定义实现,则需要覆盖该方法。
除此之外,我还有另一个关于递归validation的问题。
生成的类在其他XmlElements上缺少@valid注释。
造成这种情况的原因与我错误地使用命名空间的事实有关:
插件配置为使用特定的命名空间
-XJsr303Annotations:targetNamespace=http://www.foo.com/bar
所以XSD需要将其作为目标命名空间(例如):
善意的问候Antonio