Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java/Spring>;在请求中未发送任何正文时,使用@RequestBody处理控制器方法的错误请求响应_Java_Spring_Spring Mvc_Exception Handling_Bad Request - Fatal编程技术网

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

Java/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

长话短说:我正在创建一个应该是100%REST的API。 我正在尝试覆盖以下情况的默认响应: 我在@RestController中有一个方法,它的属性是@RequestBody

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