java spring rest 处理空请求体(400 Bad Request)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41292788/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
spring rest Handling empty request body (400 Bad Request)
提问by rvit34
I am developing RESTful app using Spring4. I want to handle case when in POST request no body was passed. I wrote custom exception handler :
我正在使用 Spring4 开发 RESTful 应用程序。我想处理在 POST 请求中没有传递正文的情况。我写了自定义异常处理程序:
@ControllerAdvice
public class MyRestExceptionHandler {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<MyErrorResponse> handleJsonMappingException(JsonMappingException ex) {
MyErrorResponse errorResponse = new MyErrorResponse("request has empty body");
return new ResponseEntity<MyErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Throwable.class)
public ResponseEntity<MyErrorResponse> handleDefaultException(Throwable ex) {
MyErrorResponse errorResponse = new MyErrorResponse(ex);
return new ResponseEntity<MyErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
@RestController
public class ContactRestController{
@RequestMapping(path="/contact", method=RequestMethod.POST)
public void save(@RequestBody ContactDTO contactDto) {...}
}
But when it happens these methods won't called. I just got response with 400 BAD REQUEST http status and empty body. Does anybody know how to handle it?
但是当它发生时,这些方法不会被调用。我刚刚收到 400 BAD REQUEST http 状态和空正文的响应。有人知道如何处理吗?
回答by rvit34
I found how to catch it. My solution is:
我找到了如何抓住它。我的解决办法是:
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
// paste custom hadling here
}
}
回答by Nguyen Minh Hien
In my case, I need to handle all requests that have invalid parameters. So I extend my class with ResponseEntityExceptionHandler
and override the method handleMissingServletRequestParameter
. You can find your own handlers defined inside the class ResponseEntityExceptionHandler
就我而言,我需要处理所有具有无效参数的请求。所以我扩展了我的类ResponseEntityExceptionHandler
并覆盖了方法handleMissingServletRequestParameter
。您可以在类中找到自己定义的处理程序ResponseEntityExceptionHandler
@ControllerAdvice
public class YourExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(Exception.class)
public final ResponseEntity handleAllExceptions(Exception ex) {
// Log and return
}
@Override
public ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
// Do your code here
return new ResponseEntity<>("YOUR REQUEST PARAMS NOT MATCH!");
}
}
回答by www
If You already have a class annotated with @ControllerAdvice
and don't want to create new one, You could use this piece of code:
如果您已经有一个类注释@ControllerAdvice
并且不想创建新的类,您可以使用这段代码:
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<?> handleMissingRequestBody(Exception ex) {
return handle(BAD_REQUEST, ex);
}
It should have the same behaviour as rvit34's solution.
它应该与rvit34的解决方案具有相同的行为。
回答by Bandi Kishore
I faced a similar issue and it didn't work for me because the component-scan
package provided didn't include the package where my @ControllerAdvice
was provided.
我遇到了类似的问题,但它对我不起作用,因为component-scan
提供的软件包不包括提供我的软件包@ControllerAdvice
。
My XML had :
我的 XML 有:
<context:component-scan base-package="com.bandi.rest" />
My package had a typo com.bandi.test.spring.exception
. After changing it to com.bandi.rest.spring.exception
it started working.
我的包裹有一个错字com.bandi.test.spring.exception
。更改为com.bandi.rest.spring.exception
它后开始工作。
@ControllerAdvice
public class SpringRestExceptionHandler {
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public @ResponseBody ResponseEntity<ErrorResponse> handleNoMethodException(HttpServletRequest request,
NoHandlerFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse(ex);
errorResponse.setErrorMessage("resource not found with exception");
return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Throwable.class)
public @ResponseBody ResponseEntity<ErrorResponse> handleDefaultException(Throwable ex) {
ErrorResponse errorResponse = new ErrorResponse(ex);
errorResponse.setErrorMessage("request has empty body or exception occured");
return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
}
}
Also, if you need to handle scenario where your requested resource was not found (bad URL), then you'll have to add another configuration to your dispatcher servlet.
此外,如果您需要处理未找到请求的资源(错误 URL)的情况,则必须向调度程序 servlet 添加另一个配置。
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
Complete Working code is available here
完整的工作代码可在此处获得
回答by Vivek
I have encountered the same issue, after spending lot of time debugging the issue I found the Hymanson is not properly deserializing the ErrorResponse
object.
我遇到了同样的问题,在花了很多时间调试问题后,我发现 Hymanson 没有正确反序列化ErrorResponse
对象。
This was because I didn't added the getters and setters for the field defined in the ErrorResponse
object. I was initializing the fields using constructor and there were no getters and setters defined for those fields.
这是因为我没有为ErrorResponse
对象中定义的字段添加 getter 和 setter 。我正在使用构造函数初始化字段,并且没有为这些字段定义 getter 和 setter。
SOLUTION:
解决方案:
So when I updated my ErrorResponse
object from
所以当我更新我的ErrorResponse
对象时
import com.fasterxml.Hymanson.annotation.JsonRootName;
import java.util.List;
@JsonRootName("error")
public class ErrorResponse {
private String message;
private List<String> details;
public ErrorResponse(String message, List<String> details) {
this.message = message;
this.details = details;
}
}
to the following one with getters and setters
到以下带有 getter 和 setter 的
import com.fasterxml.Hymanson.annotation.JsonRootName;
import java.util.List;
@JsonRootName("error")
public class ErrorResponse {
private String message;
private List<String> details;
public ErrorResponse(String message, List<String> details) {
this.message = message;
this.details = details;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<String> getDetails() {
return details;
}
public void setDetails(List<String> details) {
this.details = details;
}
}
Hymanson is now deserializing the ErrorResponse
properly and I'm getting the serialized body in the response.
Hymanson 现在正在ErrorResponse
正确地反序列化,我在响应中得到了序列化的主体。