2015-12-29 71 views
-1

所以我在Java春天一個簡單的方法,它返回一個類作爲ResponseBody:Java Spring - 如何解決HttpMessageNotWritableException無限遞歸JSON響應?

@RequestMapping(value = "update", method = RequestMethod.PUT) 
public @ResponseBody JKResponse update() { 
    return new JKResponse(); 
} 

而且JKResponse類如下:

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, 
       isGetterVisibility = JsonAutoDetect.Visibility.ANY, 
       getterVisibility = JsonAutoDetect.Visibility.ANY) 
public class JKResponse implements Serializable { 
    static final long serialVersionUID = 1L; 

    @JsonProperty 
    private List<String> stuff; 

    public JKResponse() { 
     this.stuff = new ArrayList<String>(); 
    } 

    public void setStuff(final List<String> stuff) { 
     this.stuff = stuff; 
    } 

    public List<String> getStuff() { 
     return this.stuff; 
    } 

    /* 
     THIS METHOD IS CAUSING THE INFINITE RECURSION, BUT WHY? 
    */ 
    public ResponseEntity<JResponse> getResponseEntity() { 
     return new ResponseEntity<JResponse>(this, HttpStatus.OK); 
    } 
} 

但是當我使用郵遞員叫「更新」 API的路線,我得到以下錯誤:

Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: Infinite recursion (StackOverflowError) (through reference chain: org.springframework.http.ResponseEntity["body"]->com.proj.services.JKService["responseEntity"]->org.springframework.http.ResponseEntity["body"] and so on... 

而JSON在郵遞員顯示的是:

{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body":{"responseEntity":{"headers":{},"body": and so on... 

而我無法弄清楚是什麼導致了這種情況,以及爲什麼會發生這種情況。有什麼建議?

+0

你可能需要向我們提供更多的信息。我試過你是代碼,它適用於我。 –

+0

哦,我真的想出了它爲什麼發生了(我編輯了上面的類,並添加了getResponseEntity方法,這是問題)...由於某種原因返回新的ResponseEntity <>(這,HttpStatus.OK),導致無限遞歸。這是怎麼發生的? –

+0

因爲它試圖遞歸地序列化實體。要序列化對象,必須從中獲取所有屬性,然後從其屬性中獲取所有屬性,然後從屬性的屬性等中獲取所有屬性。而且因爲其中一個屬性本身就是實體,所以它永遠不會結束。 –

回答

0

你通常不需要發送ResponseEntity給用戶,ResponseEntity是你用來告訴Spring它應該返回給用戶的數據對象。它應該像這樣使用:

@RequestMapping(value = "update", method = RequestMethod.PUT) 
public ResponseEntity<JKResponse> update() { 
    HttpHeaders responseHeaders = new HttpHeaders(); 
    responseHeaders.set("Boiling", "True"); 
    return new ResponseEntity<JKResponse>(
      new JKResponse(), responseHeaders, HttpStatus.I_AM_A_TEAPOT); 
} 

,用戶將得到這樣的:

$ curl -X PUT -i 127.0.0.1:8080/update 
HTTP/1.1 418 
Server: Apache-Coyote/1.1 
Boiling: True 
Content-Type: application/json;charset=UTF-8 
Transfer-Encoding: chunked 
Date: Tue, 29 Dec 2015 20:03:51 GMT 

{"stuff":[]}