2015-12-05 23 views
1

我有一個非常簡單的控制器操作來訪問服務層,並最終返回一個巨大的響應。響應被部分地發送,但是,在隨機的地方,最終看起來像這樣:Spring REST巨大的響應導致響應編寫器被多次調用

...,"dimensions":{"width":400,"height":394},"hostedAtS3":true},"

,我得到以下異常:

java.lang.IllegalStateException: getOutputStream() has already been called for this response

對於這一個控制器死簡單:

@JsonView(value = StickerPackView.Admin.class) 
@ApiOperation(value = "[ADMIN] Lists all categories regardless visibility", response = StickerCategory.class) 
@RequestMapping(value = "/categories/all", method = RequestMethod.GET) 
public ResponseEntity getCategories(Principal principal) { 
    return new ResponseEntity(stickerService.getAllCategories(), OK); 
} 

我試過的第一件事就是讓它DeferredResultCallable認爲可能需要更長時間才能生成響應。不幸的是,事實並非如此。當我離開這個方法並返回一些較小的響應時 - 比如單個類別 - 就沒問題。

我不知道如何處理它。這裏是full stacktrace

回答

0

所以我做了一些調試,發現它與任何遠程相關的JSON,長度或類似的東西都沒有關係。它是損壞的數據。特定模型中的一個獲得者基於已被取消的數據產生其響應。領域模型的最近更改允許它爲null,並且此方法未針對此進行調整。爲了找到它我修改了我的控制器行動,從我的問題:

@JsonView(value = StickerPackView.Admin.class) 
@ApiOperation(value = "[ADMIN] Lists all categories regardless visibility", response = StickerCategory.class) 
@RequestMapping(value = "/categories/all", method = RequestMethod.GET) 
public ResponseEntity getCategories(Principal principal, ObjectMapper mapper) throws JsonProcessingException { 
    final Collection<StickerCategory> categories = stickerService.getAllCategories(); 
    final String s = mapper.writeValueAsString(categories); 
    return new ResponseEntity(s.length(), OK); 
} 

這樣不是背後隱藏着春天JSON序列魔法序列化錯誤和暴露我的一切。我在這一次失去了太多時間。

1

檢查這對HTTP的一般理解是否不是問題。

HTTP的基本規則:一個請求,一個響應。您只能發送 一件事請求。

你提到過,當你只發送一個類別它的作品。也許,如果您正在處理大量數據,您的控制器會將其作爲多個響應進行處理。你提供的代碼是有限的,很難說出什麼原因導致了錯誤。

希望有所幫助。

+0

好吧。關於控制器沒有太多的展示。這裏的情況是需要傳輸給客戶端的數據量。我已經看到在單一請求中返回更多數據的服務,但事實上 - 將這種巨大的響應分離爲較小的響應+ HATEOAS以幫助那些正在實施此api的人員走動資源是一種可接受的解決方法。 – Mateusz