Springboot @Order 注解导致 ServletRequest 取不到值
这两天遇到一个问题,就是想做个统一登录验证过滤器
想着简单点随便加到一个现存的过滤器里面,代码如下:
package ideal4j.visual.common.filter; import ideal4j.visual.outapi.action.OutapiAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component @Order(Ordered.HIGHEST_PRECEDENCE)//控制过滤器的级别 public class AllowOriginFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest reqs = (HttpServletRequest) req; response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "0"); response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token,Access-Control-Allow-Headers"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("XDomainRequestAllowed","1"); response.setHeader("Access-Control-llow-redentials","true"); response.setHeader("x-frame-options","SAMEORIGIN"); if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { filterChain.doFilter(req, res); } } @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } }
然后我想着直接加到doFilter() 不就完事了,就像这样:
package ideal4j.visual.common.filter; import ideal4j.icity.common.enumtype.CodeEnumType; import ideal4j.icity.common.util.RequestUtils; import ideal4j.icity.common.util.SystemConstant; import ideal4j.visual.common.tableUtil.TableUtil; import ideal4j.visual.outapi.action.OutapiAction; import org.apache.commons.lang3.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component @Order(Ordered.HIGHEST_PRECEDENCE)//控制过滤器的级别 public class AllowOriginFilter implements Filter { // 是否开启登录验证 @Value("${login.verification}") private Boolean loginVerification; // 登录验证前缀 @Value("${login.url}") private String loginUrl; Logger logger = LoggerFactory.getLogger(LogMdcFilter.class); @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest reqs = (HttpServletRequest) req; //增加未登录验证逻辑 if (loginVerification && reqs.getServletPath().contains(loginUrl)){ if (ObjectUtils.isEmpty(RequestUtils.getSession().getAttribute(SystemConstant.SYSTEM_SESSION_USER_ID))) { logger.error(TableUtil.tojson(CodeEnumType.FAILURE.code, "未获取到用户登录信息")); throw new ServletException("未获取到用户登录信息"); } } response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "0"); response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token,Access-Control-Allow-Headers"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("XDomainRequestAllowed","1"); response.setHeader("Access-Control-llow-redentials","true"); response.setHeader("x-frame-options","SAMEORIGIN"); if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { filterChain.doFilter(req, res); } } @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } }
/** * 获取session */ public static HttpSession getSession() { try { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession(true); } catch (Exception e) { logger.error("任意位置获取session异常", e); return null; } }
然后怎么都获取不到SYSTEM_SESSION_USER_ID,就这个session 也是null 。但是写到另一个filter 类里面就是可以获取到的,然后我想研究一下这个@Order 注解,别人都是解释说这个注解只是声明了加载顺序,参数越小加载越早,这个我测试了是这样。
而且在我@Order(1) @Order(-1) @Order(2) @Order(-2) 的是时候,SYSTEM_SESSION_USER_ID 居然是可以获取到的。搞不明白,@Order(Ordered.HIGHEST_PRECEDENCE) 默认就是-2147483648 ,说明加载非常靠前嘛,但是为啥会影响ServletRequest呢,真实纳闷了!有没有懂的同学简单讲一讲感谢。