关于 BasicAuthenticationFilter 中的 java.lang.IllegalStateException: getOutputStream() has already been called for this response 报错问题
某天在参照大佬的配置security的时候发生了如下的错误:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:584) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:227) ~[tomcat-embed-core-9.0.41.jar:9.0.41]
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:114) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:114) ~[tomcat-embed-core-9.0.41.jar:4.0.FR]
at org.springframework.security.web.util.OnCommittedResponseWrapper.getWriter(OnCommittedResponseWrapper.java:156) ~[spring-security-web-5.4.2.jar:5.4.2]
at com.example.redisdemo.config.WebSecurityConfig.doFilterInternal(WebSecurityConfig.java:43) ~[classes/:na]
而发生问题的所指向的位置,是我配置的BasicAuthenticationFilter的所重写的doFilterInternal方法中的getWriter()位置
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String header = request.getHeader("Authorization"); if(header==null|| !header.startsWith("Bearer")) { chain.doFilter(request ,response ); response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.setContentType("application/json;charset=utf-8"); Map resultMap = new HashMap<>(); resultMap.put("code",HttpServletResponse.SC_FORBIDDEN); resultMap.put("msg","请先登陆!"); PrintWriter printWriter =response.getWriter(); printWriter.write(new ObjectMapper().writeValueAsString(resultMap)); printWriter.flush(); printWriter.close(); }else { String token =header.replace("Bearer",""); Payload<userPojo> userPojoPayload = JWTokenUtil.getUserInfoFromToken(token ,rsaKeyProperties.getPublicKey() ,userPojo.class); userPojo user= userPojoPayload.getUserInfo(); if(user!=null) { UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(user.getUsername(),null,user.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(authenticationToken); chain.doFilter(request ,response ); } } }
而chain.doFilter()作用是放行,于是我debug发现在chain.doFilter()执行之后已经存在了一个outPutStream
而我将chain.doFilter(request,response)去掉之后
response中的outputStream 为null
对比之后验证我的猜想:chain,doFiter()与我的代码之后的 想得到的response.getWriter()发生冲突,正如网上的大佬们的结论。
,doFiter()与我的代码之后的 想得到的response.getWriter()发生冲突,正如网上的大佬们的结论。