Java/Spring > Handle Bad Request response for controller method with @RequestBody when no body is sent in request

妖精的绣舞 提交于 2019-12-07 07:54:26

The solution was to simply put required = false in RequestBody annotation. After that, I could easily add some logic to throw custom exception and handle it in 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");
    } (...)

Firstly I suggest you to use BindingResult as a parameter of the POST call and check if it returns an error or not.

@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);
}

Secondly, the call can throw some of errors, a good practice is to carch them and return them itself or transform them to your own exception object. The advantage is it secures a call of all the update/modify methods (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);
}

Your control will never reach to your request method under normal circumstances. If you want a looking good page you can make use of web.xml and configure it to produce your answer.

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

Generally, if you want to go past this 400 problem, you will have to add a few annotiations to your User.java to avoid any unknown fields while de-serializing.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!