我是否需要在自定义Spring Web MessageConverter中刷新或关闭OutputStream

时间:2016-06-21 07:03:09

标签: java spring spring-mvc spring-web

我已经构建了一个自定义的Spring Web MessageConverter并重写了writeInternal方法。

我应该在getBody()OutputStream上调用flush吗? 我应该关闭getBody()OutputStream吗?

不同的转换器之间似乎存在很大的不匹配。

我想两个都没有,因为spring想要刷新输出流,请参阅https://github.com/spring-projects/spring-framework/blob/56db1af11dbe51c88c753421e022bc5389361c04/spring-web/src/main/java/org/springframework/http/converter/AbstractGenericHttpMessageConverter.java#L101

但是后来我看到gson实际上关闭了流?这只是一个错误或期望的行为? https://github.com/spring-projects/spring-framework/blob/56db1af11dbe51c88c753421e022bc5389361c04/spring-web/src/main/java/org/springframework/http/converter/json/GsonHttpMessageConverter.java#L203

然后StringConverter刷新但不关闭调用https://github.com/spring-projects/spring-framework/blob/56db1af11dbe51c88c753421e022bc5389361c04/spring-web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java#L107https://github.com/spring-projects/spring-framework/blob/56db1af11dbe51c88c753421e022bc5389361c04/spring-core/src/main/java/org/springframework/util/StreamUtils.java#L110

所以在现有技术中没有真正看到明确的答案......

1 个答案:

答案 0 :(得分:1)

永远不要在任何地方调用close()方法。

  

你永远不应该调用 close()方法,因为它会立即断开客户端套接字,因为客户端请求已被处理,它们将无法在服务器上进一步执行请求。此外,它还会删除所有配置的后置过滤器和拦截器执行,这可能会导致各种错误情况。

Why should we not call close method on response stream/writer?

响应流最终将在请求处理结束时由容器本身关闭,因此您不必担心手动调用它。只需按自己的意愿编写自定义转换器即可。

此外,您不需要将内容刷新为缓冲输出流,当缓冲区用完容量时,内容会自动刷新。

Gson转换器可能会错误地使用它,并且只要将json数据写入响应流,请求仍将终止。正如您已经知道使用它们的后果。如果这确实会在您的情况下产生任何问题,那么您可以将MappingJackson2HttpMessageConverter视为替代方案,在将json字符串写入其中后,它不会close输出流。

但是如果你编写一个新的转换器,那么最好不要在代码中的任何地方关闭流。