Java / Spring>在请求中未发送正文时,使用@RequestBody处理控制器方法的错误请求响应

时间:2017-09-01 10:02:40

标签: java spring spring-mvc exception-handling bad-request

长话短说:我正在创建应该是100%REST的API。 我尝试覆盖以下情况的默认响应: 我的@RestController中有一个方法,它将@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异常添加异常处理程序,但它也没有工作。

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

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

3 个答案:

答案 0 :(得分:4)

解决方案是在 RequestBody 注释中简单地添加 required = false 。之后,我可以轻松添加一些逻辑来抛出自定义异常并在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");
    } (...)

答案 1 :(得分:2)

首先,我建议您使用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);
}

其次,调用可能会抛出一些错误,一个好的做法是对它们进行加密并将它们自己返回或将它们转换为自己的异常对象。其优点是可以保证调用所有更新/修改方法(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);
}

答案 2 :(得分:0)

在正常情况下,您的控件永远不会触及您的请求方法。 如果您想要一个看起来很好的页面,您可以使用web.xml并对其进行配置以产生答案。

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

通常情况下,如果您想要解决此400问题,则必须在User.java中添加一些注释,以避免在反序列化时出现任何未知字段。