2014-09-03 122 views
6

我有大約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

回答

6

這不是一個小問題要解決。

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。

2

您可以返回一個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

-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。我面對這個麻煩,做了一筆交易!祝你好運。

+0

您的意思是在方法簽名下指定註釋,因爲這引發了「重複註釋@ResponseBody」編譯錯誤?謝謝! – fashuser 2014-09-04 07:07:07

+0

不,我不是說,你不應該在訪問器之後和方法的數據類型之前加註釋。用我的方式。質量掃描儀(如SonarQube)會意識到這是一個重大錯誤,需要重構!我面對它並獲得經驗。這不是「重複註釋」編譯錯誤。它會正確編譯,但你應該標準化你的代碼。 – 2014-09-04 07:12:20

+0

這是怎麼一個錯誤?這可能是代碼風格的意見,但它絕對不是一個錯誤。你的回答並不回答這個問題。 – 2014-09-04 14:42:18