15

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

当使用@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;
}
4

1 回答 1

20

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

在您的代码中,您无法创建一个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";
}

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

该缺陷已在Spring 论坛帖子中进行了讨论。

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

于 2013-06-19T22:09:17.123 回答