Java/Spring>;在请求中未发送任何正文时,使用@RequestBody处理控制器方法的错误请求响应
长话短说:我正在创建一个应该是100%REST的API。 我正在尝试覆盖以下情况的默认响应: 我在@RestController中有一个方法,它的属性是@RequestBodyJava/Spring>;在请求中未发送任何正文时,使用@RequestBody处理控制器方法的错误请求响应,java,spring,spring-mvc,exception-handling,bad-request,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 Use
@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json")
public Resource<User> registerClient(@RequestBody User user, HttpServletRequest request)
@RequestMapping(value={“register”},method=RequestMethod.POST,products=“application/hal+json”)
公共资源注册客户端(@RequestBody User,HttpServletRequest)
如果我发送一个合适的请求,这个方法就可以正常工作。但如果我不这么做,就会有问题。当一个请求的主体为空时,我会得到一个状态为400的通用Tomcat错误页面,我需要它只发送一个字符串或JSON对象 到目前为止,我尝试在RestControllerAdvice中为包org.springframework.web.binding中的所有Spring异常添加异常处理程序,但也没有成功 我已经知道,对于一些与安全相关的错误,必须在配置中创建处理程序,但我不知道是否是这样
有没有人面临过类似的问题?有什么我遗漏的吗?在正常情况下,您的控件永远不会到达您的请求方法。 如果你想要一个好看的页面,你可以使用
web.xml
并将其配置为生成你的答案
<error-page>
<error-code>404</error-code>
<location>/pages/resource-not-found.html</location>
</error-page>
404
/页面/resource-not-found.html
一般来说,如果您想解决这个400问题,您必须在
User.java
中添加一些注释,以避免在反序列化时出现任何未知字段。解决方案是简单地将required=false放在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");
} (...)
@RequestMapping(value={“register”},method=RequestMethod.POST,products=“application/hal+json”)
公共资源注册客户端(@RequestBody(required=false)用户,HttpServletRequest){
debug(“从{}请求的addClient();注册用户({})”,getClientIp(请求),user);
if(user==null){
抛出新的BadRequestException()
.setErrorCode(ErrorCode.USER_为_NULL.toString())
.setErrorMessage(“请求中的主体错误或没有主体”);
} (...)
首先,我建议您使用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);
}
@RequestMapping(value={“register”},method=RequestMethod.POST,products=“application/hal+json”)
public ResponseEntity registerClient(@RequestBody用户,HttpServletRequest请求,BindingResult brs)
如果(!brs.hasErrors()){
//添加新的
返回新的响应属性(用户,HttpStatus.CREATED);
}
返回新的ResponseEntity(brs.toString(),HttpStatus.BAD_请求);
}
其次,调用可能会抛出一些错误,一个好的做法是对它们进行carch并将其自身返回,或者将它们转换为您自己的异常对象。优点是它可以确保所有更新/修改方法(POST、PUT、PATCH)的调用安全
@ExceptionHandler(MethodArgumentNotValidException.class)
@应答器
公共响应处理方法无效异常(方法论无效异常e){
返回新的响应属性(e,HttpStatus.BAD_请求);
}
@ExceptionHandler({HttpMessageEndableException.class})
@应答器
公共响应HandleHttpMessageGenetradableException(HttpMessageGenetradableException e){
返回新的响应属性(e,HttpStatus.BAD_请求);
}
“但如果我不这样做,就会出现问题。”在哪些情况下,您不返回用户资源?@ruslanys我的意思是,当我发送一个没有正文或正文为空的POST请求时,每当我发布一个至少有{}正文的正文时,它都会作为designed@ruslanys不幸的是,它没有帮助,内容类型标题在那里,但仍然-请求中没有任何主体使用内容类型发送请求。我想问题在于它。只需检查request:Content-Type:application/json就可以了。Cos Spring仅在存在@Validated
注释时进行验证。否则,我想您缺少了内容类型。哦,是这种情况吗?控制器周围有什么问题吗?我不知道!看起来很有用,谢谢!欢迎:)有很多方法可以处理异常。我选择了这个,因为使用SpringAOP很容易记录日志。
@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);
}