Springboot @Order 注解导致 ServletRequest 取不到值

发布时间 2023-05-30 11:00:05作者: 90的生力军

这两天遇到一个问题,就是想做个统一登录验证过滤器

想着简单点随便加到一个现存的过滤器里面,代码如下:

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