带有null返回值的Spring Ajax @ResponseBody

我有大约50个使用@ResponseBody注释的控制器。

喜欢这个:

@RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET) public @ResponseBody Object getObject(@RequestParam("id") Long id) { Object object = provider.getObject(id); return object; } 

有时候getObject方法返回null 。 问题是在客户端我获得空响应而不是null

在初始实现中,我们有自定义的JsonView对象,它作为包装器而没有@ResponseBody注释。

喜欢这个:

 @RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET) public JsonView getObject(@RequestParam("id") Long id) { Object object = provider.getObject(id); return new JsonView(object); } 

所以它工作正常。

我找到了一些解决方案如何覆盖Jackson 2.0中的null序列化器? 但不幸的是,它仅适用于POJO中的字段。

您有什么想法可以处理吗?

提前致谢!

这不是一个需要解决的小问题。

Spring有一个共同的模式,如果一个处理程序方法返回null ,它意味着指示处理程序已经处理了生成和编写适当的响应内容,并且在前面不需要进一步的操作。

Spring已在其RequestResponseBodyMethodProcesser@ResponseBodyHandlerMethodReturnValueHandler实现)中应用此模式。 它检查返回值是否为null 。 它将请求设置为已处理。 如果返回值不为null ,则尝试使用适当的HttpMessageConverter对其进行序列化。

一种选择是创建自己的@ResponseBodyNull注释和相应的HandlerMethodReturnValueHandler ,它们执行相同的操作,但也处理null 。 请注意,您不一定能重用RequestResponseBodyMethodProcess的代码,因为某些HttpMessageConverters尝试使用null会失败。

另一个类似的选项是覆盖RequestResponseBodyMethodProcessor以接受null (具有上述限制)并使用RequestMappingHandlerMapping显式注册它,覆盖默认的HandlerMethodReturnValueHandler 。 你必须小心地这样做(即注册相同的),除非你想失去function。

IMO的更好解决方案是在响应主体中不处理null 。 如果getObject没有返回任何内容,那对我来说就好像是404。 设置适当的响应代码,瞧!

您始终可以将HttpServletResponse注入到处理程序方法中并执行类似的操作

 Object object = getObject(..); if (object == null) { response.getWriter().print("null"); // also set the content type to application/json } return object; 

假设您知道必须将其序列化为JSON。

您可以返回ResponseEntity,并在对象为null时将HTTP状态指定为错误:

 @RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET) public ResponseEntity getObject(@RequestParam("id") Long id) { Object object = provider.getObject(id); if (object == null ) { return new ResponseEntity (HttpStatus.BAD_REQUEST); // Or any other error status } else { return new ResponseEntity (object, HttpStatus.OK); } } 

通过这种方式,您的客户端将能够知道对象何时为空,检查响应状态。

如果你确实需要返回null值,你可以配置Jackson来序列化它(来自tkuty的代码):

       NON_NULL       

我希望这对你有帮助。

首先,我建议你不要这样写:

 @RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET) public @ResponseBody Object getObject(@RequestParam("id") Long id) { /* */ } 

将其作为标准代码。 试试这个:

 @RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET) @ResponseBody public Object getObject(@RequestParam("id") Long id) { Object object = provider.getObject(id); return object; } 

我有高质量扫描仪的经验,这种方式可以帮助您避免扫描仪发现的错误。 关于您的问题,您可以尝试使用Transformer或addScala()来返回POJO。 我遇到了这个麻烦,并达成了协议! 祝你好运。