带有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
( @ResponseBody
的HandlerMethodReturnValueHandler
实现)中应用此模式。 它检查返回值是否为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
通过这种方式,您的客户端将能够知道对象何时为空,检查响应状态。
如果你确实需要返回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。 我遇到了这个麻烦,并达成了协议! 祝你好运。