本文介绍了使用Spring MVC,接受带有错误JSON的POST请求会导致返回默认的400错误代码服务器页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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





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



这是我的代码:

  @RequestMapping(value =/ trackingNumbers,method = RequestMethod.POST,consume =application / json)
@ResponseBody
public ResponseEntity< ;字符串> 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>(结果,状态);

返回回复;
}

@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,这不是TrackingNumber对象的有效表单+
({\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>(结果,状态);

返回回复;
}


解决方案

这是一个问题使用Spring - JSON(jackson)@RequestBody编组引发了一个尴尬的异常 - 这是在Spring 3.1M2中通过弹出一个 org.springframework.http.converter.HttpMessageNotReadableException 来解决的。邮件正文丢失或无效。



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

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

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



该缺陷在春季论坛帖子。



注意:我开始使用Jetty 9.0.0.M4进行测试但是有一些其他内部问题阻止 @ExceptionHandler 完成,所以根据你的容器(Jetty,Tomcat,其他)版本,你可能需要得到一个与任何东西很好地兼容的新版本你正在使用的Spring版本。


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.

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.

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.

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?

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;
}
解决方案

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

In your code you cannot create a ResponseStatus since 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.

@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.

The defect was discussed on this Spring forum post.

Note: I started testing with Jetty 9.0.0.M4 but that had some other internal issues stopping the @ExceptionHandler completing, 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.

这篇关于使用Spring MVC,接受带有错误JSON的POST请求会导致返回默认的400错误代码服务器页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 15:45