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

UpA*_*ght 13 java rest spring-mvc

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

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

那么问题是,当Spring只是无效的语法时,它实际上不会抛出异常......至少不是我能看到的.它只是从服务器返回默认错误页面,无论是Tomcat,Glassfish等.

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

这是我的代码:

@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;
}
Run Code Online (Sandbox Code Playgroud)

and*_*dyb 15

这是提出与春天的一个问题SPR-7439- JSON(杰克逊)@RequestBody编组抛出异常尴尬-被具有春天抛出一个固定在Spring 3.1M2 org.springframework.http.converter.HttpMessageNotReadableException在丢失或无效的消息体的情况.

在你的代码无法创建ResponseStatus,因为它是抽象的,但我测试赶上这个例外有一个简单的与码头9.0.3.v20130506运行春季3.2.0.RELEASE本地方法.

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

我收到了400状态"错误"字符串响应.

这个缺陷在春季论坛帖子中进行了讨论.

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

  • 编辑自 @PavelHoral 似乎因其“个人”性质而受到冒犯 (2认同)