Spring Ajax @ResponseBody返回空值
我有大约50个使用@ResponseBody注释的控制器。Spring Ajax @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
。
在最初的实现中,我们定制了不带@ResponseBody注释的包装器对象JsonView
。
像这样:
@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领域。
你有什么想法可以如何处理?
在此先感谢!
这不是一个小问题要解决。
Spring有,其中,如果处理方法返回null
,它是指以指示该处理器已经处理了生产和写入适当的响应内容,并且没有进一步的操作是必要的前面有一个共同的模式。
Spring在其RequestResponseBodyMethodProcesser
(@ResponseBody
的HandlerMethodReturnValueHandler
实现)中应用了此模式。它检查返回值是否为null
。它将请求设置为已处理。如果返回值不是null
,它会尝试使用适当的HttpMessageConverter
将其序列化。
一种选择是创建您自己的@ResponseBodyNull
注释和相应的HandlerMethodReturnValueHandler
,除了也处理null
之外,它们的作用相同。请注意,您无法重复使用RequestResponseBodyMethodProcess
中的代码,因为某些HttpMessageConverters
会尝试使用null
失败。
另一个类似的选项是覆盖RequestResponseBodyMethodProcessor
接受null
(有限制上述),并与您的RequestMappingHandlerMapping
明确注册,覆盖默认HandlerMethodReturnValueHandler
秒。你必须小心翼翼(即注册相同的),除非你想失去功能。
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并指定HTTP状态的错误时,对象为null:
@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检查响应状态。
如果你确实需要返回您可以配置杰克逊序列化的空值(从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>
我希望这可以帮助您。
不幸的是,任何方法在我的情况下都不起作用:1)第一个方法继续返回空响应,如下代码所示:\t \t Object body = responseEntity.getBody();如果(body!= null){ \t \t \t writeWithMessageConverters(body,returnType,inputMessage,outputMessage); \t \t} \t \t否则{ \t \t \t //冲洗头到HttpServletResponse的 \t \t \t outputMessage.getBody(); \t \t}。所以它只是preint null作为priviues并避免writeWithMessageConverters方法。 – fashuser 2014-09-04 08:23:21
您的第二个建议将不起作用,因为'null'永远不会到达'MappingJackson2HttpMessageConverter',它将停止在'RequestResponseBodyMethodProcessor'处。 – 2014-09-04 16:11:30
首先,我建议你不要应该写这样的:
@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。我面对这个麻烦,做了一笔交易!祝你好运。
您的意思是在方法签名下指定注释,因为这引发了“重复注释@ResponseBody”编译错误?谢谢! – fashuser 2014-09-04 07:07:07
不,我不是说,你不应该在访问器之后和方法的数据类型之前加注释。用我的方式。质量扫描仪(如SonarQube)会意识到这是一个重大错误,需要重构!我面对它并获得经验。这不是“重复注释”编译错误。它会正确编译,但你应该标准化你的代码。 – 2014-09-04 07:12:20
这是怎么一个错误?这可能是代码风格的意见,但它绝对不是一个错误。你的回答并不回答这个问题。 – 2014-09-04 14:42:18
你能告诉我们这个泛型JsonView类来自哪个库吗? – 2014-09-04 15:13:17