关于 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 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()发生冲突,正如网上的大佬们的结论。