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

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

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

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

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

这是我的代码:

@RequestMapping(value = "/trackingNumbers", method = RequestMethod.POST, consumes = "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 response = new ResponseEntity(result, status); return response; } @ExceptionHandler({NullPointerException.class, EOFException.class}) @ResponseBody public ResponseEntity 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 response = new ResponseEntity(result, status); return response; } 

这是Spring SPR-7439一个问题–JSON(jackson)@RequestBody编组抛出尴尬的exception – 这是在Spring 3.1M2中通过弹出一个org.springframework.http.converter.HttpMessageNotReadableException在一个缺失的情况下修复的或无效的邮件正文。

在你的代码中,你不能创建一个ResponseStatus因为它是抽象的,但我测试了在本地使用一个更简单的方法捕获此exception,并在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状态“错误”字符串响应。

这个缺陷在本春季论坛post中进行了讨论。

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