我有一个非常简单的控制器动作,可以访问服务层,并最终返回一个巨大的响应。响应部分发送,但在随机位置,它最终看起来像这样:
...,"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);
}
我尝试的第一件事就是让它DeferredResult
或Callable
认为可能需要更长的时间来生成响应。不幸的是,事实并非如此。当我离开那里的方法并最终返回一些较小的响应 - 比如单一类别 - 就可以了。
我不知道如何处理它。这是full stacktrace。
答案 0 :(得分:1)
检查这是否是对HTTP的一般理解的问题。
HTTP的基本规则:一个请求,一个响应。你只能寄回去 请求的一件事。
您提到当您只发送一个类别时,它可以正常工作。也许,如果您正在处理大量数据,您的控制器会将其作为多个响应进行处理。您提供的代码有限,很难说究竟是什么原因导致错误。
希望有所帮助。
答案 1 :(得分:0)
所以我做了一些调试,发现它与任何远程与JSON,长度或类似的东西无关。这是损坏的数据。特定模型中的一个getter基于无效的数据生成其响应。最近域模型的更改允许它为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);
}
通过这种方式,序列化错误并没有隐藏在Spring Json序列化魔法背后,并且暴露了一切给我。我在这个上花了太多时间。