Используя Spring Boot 2.1.0, мы получаем следующую трассировку стека на одном из наших серверов. Это не происходит на других серверах, хотя. Мы используем одну и ту же базовую линию для всех серверов.
java.lang.IllegalStateException: getWriter() has already been called for this response
at org.apache.catalina.connector.Response.getOutputStream(Response.java:548)
at org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:210)
at javax.servlet.ServletResponseWrapper.getOutputStream(ServletResponseWrapper.java:100)
at org.springframework.boot.web.servlet.support.ErrorPageFilter$ErrorWrapperResponse.getOutputStream(ErrorPageFilter.java:381)
at javax.servlet.ServletResponseWrapper.getOutputStream(ServletResponseWrapper.java:100)
at javax.servlet.ServletResponseWrapper.getOutputStream(ServletResponseWrapper.java:100)
at org.springframework.security.web.util.OnCommittedResponseWrapper.getOutputStream(OnCommittedResponseWrapper.java:139)
at com.mycompany.rest.controller.ReferralController.viewUploadedDocument(ReferralController.java:160)
at com.mycompany.rest.controller.ReferralController$$FastClassBySpringCGLIB$$ff8620dc.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
--
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at com.mycompany.rest.security.JwtTokenFilter.doFilter(JwtTokenFilter.java:52)
Метод контроллера. Насколько я могу судить, Writer / OutputStream извлекается только один раз.
@GetMapping("/document/{documentId}")
@ApiResponses(value = { @ApiResponse(code = 400, message = "Blah") })
public void viewUploadedDocument(@PathVariable("documentId") final Long documentId,
final HttpServletRequest request, final HttpServletResponse response) throws IOException {
final MyDocument result = myService.getResult(documentId);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
response.setHeader("Content-Disposition", "attachment; filename=\"" + result.getFileName() + "\"");
final byte[] content = result.getContent();
if (content == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Not found");
} else {
response.setContentLength(content.length);
final OutputStream os = response.getOutputStream();
os.write(content, 0, content.length);
os.close();
}
}
По какой-то причине getWriter уже был вызван, но условие ошибки не должно вызываться при наличии содержимого.
Может ли аннотация Swagger @ApiResponses вызвать это?
Есть идеи, почему это происходит?
Спасибо.