java 使用 Spring MVC,接受带有错误 JSON 的 POST 请求会导致返回默认的 400 错误代码服务器页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17201072/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:18:04  来源:igfitidea点击:

Using Spring MVC, accepting POST requests with bad JSON leads to a default 400 error code server page being returned

javarestspring-mvc

提问by UpAllNight

I am working on a REST api. Receiving a POST message with bad JSON (e.g. { sdfasdfasdf } ) causes Spring to return the default server page for a 400 Bad Request Error. I do not want to return a page, I want to return a custom JSON Error object.

我正在研究 REST api。接收带有错误 JSON 的 POST 消息(例如 { sdfasdfasdf } )会导致 Spring 返回 400 Bad Request 错误的默认服务器页面。我不想返回一个页面,我想返回一个自定义的 JSON 错误对象。

I can do this when there is an exception thrown by using an @ExceptionHandler. So if it is a blank request or a blank JSON object (e.g. { } ), it will throw a NullPointerException and I can catch it with my ExceptionHandler and do whatever I please.

当使用@ExceptionHandler 抛出异常时,我可以这样做。因此,如果它是一个空白请求或一个空白 JSON 对象(例如 { } ),它将抛出 NullPointerException 并且我可以用我的 ExceptionHandler 捕获它并做任何我想做的事情。

The problem then, is that Spring doesn't actually throw an exception when it is just invalid syntax... at least not that I can see. It simply returns the default error page from the server, whether it is Tomcat, Glassfish, etc.

那么问题是,当 Spring 只是无效语法时,它实际上并没有抛出异常……至少我看不到。它只是简单地从服务器返回默认错误页面,无论是 Tomcat、Glassfish 等。

So my question is how can I "intercept" Spring and cause it to use my exception handler or otherwise prevent the error page from displaying and instead return a JSON error object?

所以我的问题是如何“拦截”Spring 并使其使用我的异常处理程序或以其他方式阻止错误页面显示并返回一个 JSON 错误对象?

Here is my code:

这是我的代码:

@RequestMapping(value = "/trackingNumbers", method = RequestMethod.POST, consumes = "application/json")
@ResponseBody
public ResponseEntity<String> setTrackingNumber(@RequestBody TrackingNumber trackingNumber) {

    HttpStatus status = null;
    ResponseStatus responseStatus = null;
    String result = null;
    ObjectMapper mapper = new ObjectMapper();

    trackingNumbersService.setTrackingNumber(trackingNumber);
    status = HttpStatus.CREATED;
    result = trackingNumber.getCompany();


    ResponseEntity<String> response = new ResponseEntity<String>(result, status);

    return response;    
}

@ExceptionHandler({NullPointerException.class, EOFException.class})
@ResponseBody
public ResponseEntity<String> resolveException()
{
    HttpStatus status = null;
    ResponseStatus responseStatus = null;
    String result = null;
    ObjectMapper mapper = new ObjectMapper();

    responseStatus = new ResponseStatus("400", "That is not a valid form for a TrackingNumber object " + 
            "({\"company\":\"EXAMPLE\",\"pro_bill_id\":\"EXAMPLE123\",\"tracking_num\":\"EXAMPLE123\"})");
    status = HttpStatus.BAD_REQUEST;

    try {
        result = mapper.writeValueAsString(responseStatus);
    } catch (IOException e1) {
        e1.printStackTrace();
    }

    ResponseEntity<String> response = new ResponseEntity<String>(result, status);

    return response;
}

回答by andyb

This was raised as an issue with Spring SPR-7439- JSON (Hymanson) @RequestBody marshalling throws awkward exception - which was fixed in Spring 3.1M2 by having Spring throw a org.springframework.http.converter.HttpMessageNotReadableExceptionin the case of a missing or invalid message body.

这是作为 Spring 的一个问题提出的SPR-7439- JSON (Hymanson) @RequestBody marshalling 引发了尴尬的异常 - 在 Spring 3.1M2 中通过让 Springorg.springframework.http.converter.HttpMessageNotReadableException在消息正文丢失或无效的情况下抛出 a来修复该异常。

In your code you cannot create a ResponseStatussince it is abstract but I tested catching this exception with a simpler method locally with Spring 3.2.0.RELEASE running on Jetty 9.0.3.v20130506.

在您的代码中,您无法创建一个,ResponseStatus因为它是抽象的,但我测试了使用在 Jetty 9.0.3.v20130506 上运行的 Spring 3.2.0.RELEASE 在本地使用更简单的方法捕获此异常。

@ExceptionHandler({org.springframework.http.converter.HttpMessageNotReadableException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public String resolveException() {
    return "error";
}

and I received a 400 status "error" String response.

我收到了 400 状态“错误”字符串响应。

The defect was discussed on thisSpring forum post.

这种缺陷在讨论这个春季论坛的帖子。

Note:I started testing with Jetty 9.0.0.M4 but that had some other internal issues stopping the @ExceptionHandlercompleting, so depending on your container (Jetty, Tomcat, other) version you might need to get a newer version that plays nicely with whatever version of Spring you are using.

注意:我开始使用 Jetty 9.0.0.M4 进行测试,但是还有一些其他内部问题阻止了@ExceptionHandler完成,因此根据您的容器(Jetty、Tomcat、其他)版本,您可能需要获得一个新版本,该版本可以与任何版本很好地配合使用您正在使用的 Spring。