我有大约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<Object> getObject(@RequestParam("id") Long id) {
Object object = provider.getObject(id);
return new JsonView(object);
}
所以它工作正常。
我在How do you override the null serializer in Jackson 2.0?找到了一些解决方案但不幸的是它仅适用于POJO中的字段。
您有什么想法可以处理吗?
提前致谢!
答案 0 :(得分:6)
这不是一个需要解决的小问题。
Spring有一个共同的模式,如果一个处理程序方法返回null
,它意味着指示处理程序已经处理了生成和编写适当的响应内容,并且前面不需要进一步的操作
Spring已在其RequestResponseBodyMethodProcesser
(HandlerMethodReturnValueHandler
的{{1}}实现)中应用此模式。它检查返回值是否为@ResponseBody
。它将请求设置为已处理。如果返回值不是null
,则会尝试使用适当的null
对其进行序列化。
一种选择是创建自己的HttpMessageConverter
注释和相应的@ResponseBodyNull
,除了处理HandlerMethodReturnValueHandler
外,它们也会相同。请注意,您无法重复使用null
中的代码,因为有些RequestResponseBodyMethodProcess
会尝试使用HttpMessageConverters
失败。
另一个类似的选项是覆盖null
以接受RequestResponseBodyMethodProcessor
(具有上述限制),并使用null
明确注册,覆盖默认RequestMappingHandlerMapping
。你必须小心地这样做(即注册相同的),除非你想失去功能。
更好的解决方案IMO将不在响应机构中处理HandlerMethodReturnValueHandler
。如果null
没有返回任何内容,那对我来说就好像是404。设置适当的响应代码,瞧!
您始终可以将getObject
注入到处理程序方法中并执行类似
HttpServletResponse
假设您知道必须将其序列化为JSON。
答案 1 :(得分:2)
当对象为空时,您可以返回ResponseEntity并将HTTP状态指定为错误:
@RequestMapping(value = "/someUrl.controller", method = RequestMethod.GET)
public ResponseEntity<Object> getObject(@RequestParam("id") Long id) {
Object object = provider.getObject(id);
if (object == null ) {
return new ResponseEntity<Object> (HttpStatus.BAD_REQUEST); // Or any other error status
} else {
return new ResponseEntity<Object> (object, HttpStatus.OK);
}
}
通过这种方式,您的客户端将能够知道对象何时为空,检查响应状态。
如果您确实需要返回null值,可以将Jackson配置为序列化(来自tkuty的代码):
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="serializationInclusion">
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
我希望这对你有所帮助。
答案 2 :(得分:-3)
首先,我建议你不要这样写:
@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。我遇到了这个麻烦,并达成了协议!祝你好运。