2017-09-01 71 views
0

长话短说:我正在创建应该是100%REST的API。 我试图改写下列情况下默认响应: 我有我的@RestController的方法有@RequestBody作为一个属性Java/Spring>当请求中没有主体时,处理带有@RequestBody的控制器方法的错误请求响应

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public Resource<User> registerClient(@RequestBody User user, HttpServletRequest request) 

,如果我发送的方法工作得很好适当的要求。但是当我不这样做的时候有一个问题。当请求有空的时候,我得到一个状态为400的通用Tomcat错误页面,我需要它只发送一个字符串或一个JSON对象。

到目前为止,我尝试在我的RestControllerAdvice中为包org.springframework.web.binding中的所有Spring异常添加异常处理程序,但它也不起作用。

我已经意识到,对于一些与安全相关的错误,必须在配置中创建处理程序,但我不知道是否属于这种情况。

有没有人遇到过类似的问题?有什么我失踪?

+0

“但是当我不这样做的时候有一个问题。” 在哪些情况下你不会返回用户资源? – ruslanys

+0

@ruslanys我的意思是,当我发送POST请求没有身体或空身体,每当我发布身体至少** {} **它的处理如设计 –

+0

@ruslanys不幸的是,它并没有帮助,内容类型标题在那里,但仍然 - 请求中没有正文带来提及的问题 –

回答

2

解决方案是简单地把required = false in RequestBody注释。之后,我可以轻松添加一些逻辑来引发自定义异常,并在ControllerAdvice中处理它。

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public Resource<User> registerClient(@RequestBody(required = false) User user, HttpServletRequest request){ 
    logger.debug("addClient() requested from {}; registration of user ({})", getClientIp(request), user); 
    if(user == null){ 
     throw new BadRequestException() 
       .setErrorCode(ErrorCode.USER_IS_NULL.toString()) 
       .setErrorMessage("Wrong body or no body in reqest"); 
    } (...) 
0

在正常情况下,您的控件永远无法达到您的请求方法。 如果你想要一个看起来不错的页面,你可以使用web.xml并配置它来产生你的答案。

<error-page> 
    <error-code>404</error-code> 
    <location>/pages/resource-not-found.html</location> 
</error-page> 

一般来说,如果你想要去的过去,这400问题,你将有几个annotiations添加到您的User.java以避免同时反序列任何未知领域。

1

首先,我建议你使用BindingResult作为POST调用的参数并检查它是否会返回一个错误或没有。

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public ResponseEntity<?> registerClient(@RequestBody User user, HttpServletRequest request, BindingResult brs) 
    if (!brs.hasErrors()) { 
     // add the new one 
     return new ResponseEntity<User>(user, HttpStatus.CREATED); 
    } 
    return new ResponseEntity<String>(brs.toString(), HttpStatus.BAD_REQUEST); 
} 

其次,呼叫可以抛出一些错误的,一个好的做法是carch他们并返回他们自己或他们转化为自己的异常对象。它的优点是保证了所有更新/修改方法的调用(POST,PUT,PATCH)

@ExceptionHandler(MethodArgumentNotValidException.class) 
@ResponseBody 
public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { 
    return new ResponseEntity<List<MethodArgumentNotValidException>>(e, HttpStatus.BAD_REQUEST); 
} 

@ExceptionHandler({HttpMessageNotReadableException.class}) 
@ResponseBody 
public ResponseEntity<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { 
    return new ResponseEntity<List<HttpMessageNotReadableException>>(e, HttpStatus.BAD_REQUEST); 
} 
+0

不知道!看起来非常有用,谢谢! –

+0

欢迎:)有很多方法来处理异常。我选择了这个,因为使用Spring AOP很容易记录。 –