首页 > 解决方案 > Spring Boot Error getOutputStream() has already been called for this response after forward

问题描述

我目前正在开发一个 Spring Boot 应用程序。我为 httpBasic 身份验证实现了 Spring Boot 安全性。身份验证成功后,我的自定义过滤器方法就会被调用。

protected void onSuccessfulAuthentication(javax.servlet.http.HttpServletRequest request,
        javax.servlet.http.HttpServletResponse response, Authentication authResult) throws IOException {
Iterator<? extends GrantedAuthority> it = authResult.getAuthorities().iterator();
        switch (it.next().getAuthority()) {
        case (MyConstants.ROLE_USER): {
            try {
                request.getRequestDispatcher("/user/data").forward(request, response);  break;
        } catch (ServletException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

所以我想将我需要的带有 JSON 数据的 rquest 对象转发到我的 RestController 端点。这行得通。在我的控制器中,我想返回带有数据和 Http 状态代码的 ResponseEntity。

@RequestMapping(value="/upload", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity< HttpStatus> upload(@RequestBody String uploadData){

    ResponseEntity<String> httpStatus = sendExchangeToRestApi(MediaType.APPLICATION_JSON, uploadData,
            "http://localhost:8080/upload", HttpMethod.PUT);
    return new ResponseEntity<String>("Test". HttpStatus.OK);

}

我用邮递员对此进行了测试。输出没问题,所以我在 Body 输出中得到了 Status 200 和 Test。但我遇到以下错误:

servlet [dispatcherServlet] 的 Servlet.service() 在路径 [] 的上下文中抛出异常 [java.lang.IllegalStateException: getOutputStream() 已经为此响应调用] 根本原因 java.lang.IllegalStateException: getOutputStream() 已经在 javax.servlet.ServletResponseWrapper 的 org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:227) 的 org.apache.catalina.connector.Response.getWriter(Response.java:582) 上被要求对此响应。 getWriter(ServletResponseWrapper.java:109) at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:109) at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:109) at org.springframework.security.web.util.OnCommittedResponseWrapper .getWriter(OnCommittedResponseWrapper.java:149) 在 javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:109) 在 org.springframework.security.web.util.OnCommittedResponseWrapper.getWriter(OnCommittedResponseWrapper.java:149) 在 org.apache.jasper.runtime.JspWriterImpl.initOut (JspWriterImpl.java:115) 在 org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:108) 在 org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:172) 在 org.apache。 jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:120) at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75) at org.apache.jsp.view.login_jsp._jspService(login_jsp.java: 171) 在 org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 在 javax.servlet.http.HttpServlet。服务(HttpServlet.java:741)在 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:458) 在 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386) 在 org.apache .jasper.servlet.JspServlet.service(JspServlet.java:330) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231 ) 在 org.apache.catalina.core.ApplicationDispatcher 的 org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) 的 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)。 doInclude(ApplicationDispatcher.java:580) 在 org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:516) 在 org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:162) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) at org.springframework.web.servlet.DispatcherServlet。渲染(DispatcherServlet.java:1370)在 org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1116) 在 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055) 在 org.springframework .web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) 在 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998) 在 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java :890) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:634) 在 org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:741) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:231) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) 在 org. org.springframework.security.web.authentication.www.BasicAuthenticationFilter 的 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 的 apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)。 doFilterInternal(BasicAuthenticationFilter.java:215) 在 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.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 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 ) 在 org.springframework.security.web.access。org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter( FilterChainProxy.java:334) 在 org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org .springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 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) 在 org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) 在 org.springframework.security 的 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) .web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:215) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.authentication.www。 BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:215) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)在 org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework。security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) at org.springframework.security.web.header。 HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)在 org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 在 org.springframework.security.web .context.request.async。WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)在 org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) 在 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) 在 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:357) 在 org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache。 catalina.core。ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 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.web.filter.FormContentFilter.doFilterInternal(FormContentFilter .java:92) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina 的 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)。核心.ApplicationFilterChain。doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) 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.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter .filterAndRecordMetrics(WebMvcMetricsFilter.java:154) 在 org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:122) 在 org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter .doFilterInternal(WebMvcMetricsFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain 的 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) .doFilter(ApplicationFilterChain.java:166) 在 org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org. apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve. java:199) 在 org.apache.catalina。core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) 在 org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:343) 在 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) 在 org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 在 org.apache.coyote。 AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) 在 org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 在 java.util.concurrent.ThreadPoolExecutor$Worker。在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(Unknown Source) 运行(Unknown Source)

所以似乎 getOutputStream()/getWriter() 被多次调用,但我不知道为什么。

标签: javaspring-bootspring-securitybasic-authenticationrequestdispatcher

解决方案


您应该注意的一件事是,每个微服务都应该有自己的数据库,如果您的所有微服务共享同一个数据库,那么数据库将成为您的中心合同,并且总是很难进行更改,因为您永远不知道哪个微服务使用什么。

说到 RabbitMQ,我个人认为它是有史以来最好的 Message-Broker。我建议您拥有一个队列/微服务和一个 Exchange/微服务。您可以轻松配置 RabbitMQ 以根据路由键在队列之间重定向消息。

希望这有助于最好的问候

布里姆·哈吉里扎伊


推荐阅读