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呢,真实纳闷了!有没有懂的同学简单讲一讲感谢。

浙公网安备 33010602011771号