Spring Ajax @ResponseBody返回空值

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领域。

你有什么想法可以如何处理?

在此先感谢!

+0

你能告诉我们这个泛型JsonView类来自哪个库吗? – 2014-09-04 15:13:17

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

Spring有,其中,如果处理方法返回null,它是指以指示该处理器已经处理了生产和写入适当的响应内容,并且没有进一步的操作是必要的前面有一个共同的模式。

Spring在其RequestResponseBodyMethodProcesser@ResponseBodyHandlerMethodReturnValueHandler实现)中应用了此模式。它检查返回值是否为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> 

我希望这可以帮助您。

+0

不幸的是,任何方法在我的情况下都不起作用: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

+0

您的第二个建议将不起作用,因为'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。我面对这个麻烦,做了一笔交易!祝你好运。

+0

您的意思是在方法签名下指定注释,因为这引发了“重复注释@ResponseBody”编译错误?谢谢! – fashuser 2014-09-04 07:07:07

+0

不,我不是说,你不应该在访问器之后和方法的数据类型之前加注释。用我的方式。质量扫描仪(如SonarQube)会意识到这是一个重大错误,需要重构!我面对它并获得经验。这不是“重复注释”编译错误。它会正确编译,但你应该标准化你的代码。 – 2014-09-04 07:12:20

+0

这是怎么一个错误?这可能是代码风格的意见,但它绝对不是一个错误。你的回答并不回答这个问题。 – 2014-09-04 14:42:18