最近Spring Boot项目做单点登录对接的时候,在配置过滤器的时候,找了几种方法,记录一下。欢迎评论补充沟通~
由于之前JAVA Web项目最开始都有web.xml配置,随着框架慢慢的进化,从Spring Boot开始,已经没有了web.xml配置文件。
那原来在web.xml里,配置的filter过滤器,在Spring Boot中怎么配置呢?
实现Filter接口,使用@WebFilter注解
过滤和实现都有,但是@order排序只能根据过滤器的类名排序
使用FilterRegistrationBean
主要是过滤,实现类要单独写,可以自定义排序
实现ServletContextInitializer接口
主要是过滤,实现类要单独写,目前没试能不能排序
<filter>
<filter-name>SPDispacherfilter-name>
<filter-class>org.xxx.SpFilterWrapperfilter-class>
filter>
<filter>
<filter-name>SessionIntegrationFilterfilter-name>
<filter-class>org.xxx.AgentSessionIntegrationFilterfilter-class>
filter>
<filter>
<filter-name>AuthorizationFilterfilter-name>
<filter-class>org.xxx.AgentAuthzBaseRoleFilterfilter-class>
filter>
<filter-mapping>
<filter-name>SPDispacherfilter-name>
<url-pattern>*.jspurl-pattern>
filter-mapping>
<filter-mapping>
<filter-name>SPDispacherfilter-name>
<url-pattern>/service/*url-pattern>
filter-mapping>
<filter-mapping>
<filter-name>SPDispacherfilter-name>
<url-pattern>/SAML2/*url-pattern>
filter-mapping>
<filter-mapping>
<filter-name>SessionIntegrationFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter-mapping>
<filter-name>AuthorizationFilterfilter-name>
<url-pattern>/service/*url-pattern>
filter-mapping>
这种方式,可以在doFilter()方法中,写具体的过滤逻辑。
@WebFilter注解中写上属性,可以设置过滤的路径等等。
以上web.xml里的filter-class为已经封装好的第三方jar里的类。所以此处代码演示,与以上web.xml无关。
属性名 | 类型 | 默认值 | 作用 |
---|---|---|---|
filterName | String | “” | 指定过滤器的 name 属性 |
value | String[] | {} | 该属性等价于 urlPatterns 属性。两者不应该同时使用 |
urlPatterns | String[] | {} | 指定一组过滤器的 URL 匹配模式 |
servletNames | String[] | {} | 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中的取值 |
dispatcherTypes | DispatcherType | DispatcherType.REQUEST | 指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST |
initParams | WebInitParam[] | {} | 指定一组过滤器初始化参数 |
asyncSupported | boolean | false | 声明过滤器是否支持异步操作模式 |
description | String | “” | 该过滤器的描述信息 |
displayName | String | “” | 该过滤器的显示名,通常配合工具使用 |
备注:自定义类上,可以设置过滤器的顺序@Order(1),这个网上说不好用,还是根据过滤器类名排序的。
代码如下:
package org.framework.modules.system.paramsUtil;
import com.alibaba.fastjson.JSONObject;
import org.framework.common.util.encryption.AesEncryptUtil;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
@WebFilter(urlPatterns = "/*")
// @WebFilter(filterName = "testFilter", urlPatterns = "/*",
// initParams = @WebInitParam(name = "noFilterUrl", value = "/test"))
public class ParamsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO 此处写具体的处理逻辑
ServletRequest requestWrapper = null;
HashMap paramsOld = new HashMap(request.getParameterMap());
if(!ObjectUtils.isEmpty(paramsOld)){
JSONObject json = (JSONObject) JSONObject.toJSON(paramsOld);
if(json.containsKey("xxxcryptparams")){
try {
String ss = json.getString("xxxencryptparams");
...
} catch (Exception e) {
e.printStackTrace();
}
if(request instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) request,json);
}
}
}
if(requestWrapper == null) {
chain.doFilter(request, response);
} else {
chain.doFilter(requestWrapper, response);
}
}
@Override
public void destroy() {
}
}
@SpringBootApplication
@ServletComponentScan
public class JeecgApplication {
public static void main(String[] args) {
...
}
}
这种方式,适合过滤器的具体类已经写好的情况,这里做一下拦截。
可以自定义类,也可以是导入第三方的jar写好的类。
注意,这个自定义类,也不能加@Component或@Configuration注解,加了就会初始化Filter了,过滤全部的路径了。
package org.framework.modules.system.paramsUtil;
import javax.servlet.*;
import java.io.IOException;
public class ParamsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO 过滤器逻辑
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
@Bean
public FilterRegistrationBean<OrderFilter> orderFilter() {
FilterRegistrationBean<OrderFilter> filter = new FilterRegistrationBean<>();
filter.setName("paramsFilter");
filter.setFilter(new ParamsFilter());
// 指定优先级
filter.setOrder(-1);
return filter;
}
与web.xml配套:
package org.framework.modules.bsp.filter;
import org.xxx.AgentAuthzBaseRoleFilter;
import org.xxx.AgentSessionIntegrationFilter;
import org.xxx.SpFilterWrapper;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
@Configuration
public class MyBspFilter {
/**
* 注册registerSPDispacher
*/
@Bean
public FilterRegistrationBean registerSPDispacher() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new SpFilterWrapper());
registration.addUrlPatterns(new String[] {"*.jsp","/service/*","/SAML2/*"});
registration.setName("SPDispacher");
registration.setOrder(1); //值越小,Filter越靠前。
return registration;
}
/**
* 注册SessionIntegrationFilter
*/
@Bean
public FilterRegistrationBean registerSessionIntegrationFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new AgentSessionIntegrationFilter());
registration.addUrlPatterns("/*");
registration.setName("SessionIntegrationFilter");
registration.setOrder(2); //值越小,Filter越靠前。
return registration;
}
/**
* 注册SessionIntegrationFilter
*/
@Bean
public FilterRegistrationBean registerAuthorizationFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new AgentAuthzBaseRoleFilter());
registration.addUrlPatterns("/service/*");
registration.setName("AuthorizationFilter");
registration.setOrder(3); //值越小,Filter越靠前。
return registration;
}
}
这种方式,适合过滤器的具体类已经写好的情况,这里做一下过滤。
可以自定义类,也可以是导入第三方的jar写好的类。此处以与web.xml配套的第三方jar演示。
与web.xml配套:
package org.framework.modules.bsp.filter;
import org.xxx.AgentAuthzBaseRoleFilter;
import org.xxx.AgentSessionIntegrationFilter;
import org.xxx.service.SpFilterWrapper;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Configuration;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@Configuration
public class MyWebApplicationInitializer implements ServletContextInitializer {
@Override
public void onStartup(ServletContext sc) throws ServletException {
FilterRegistration.Dynamic sPDispacher = sc.addFilter("SPDispacher", SpFilterWrapper.class);
sPDispacher.addMappingForUrlPatterns(null, false, "*.jsp");
sPDispacher.addMappingForUrlPatterns(null, false, "/service/*");
sPDispacher.addMappingForUrlPatterns(null, false, "/SAML2/*");
FilterRegistration.Dynamic sessionIntegrationFilter = sc.addFilter("SessionIntegrationFilter", AgentSessionIntegrationFilter.class);
sessionIntegrationFilter.addMappingForUrlPatterns(null, false, "/*");
FilterRegistration.Dynamic authorizationFilter = sc.addFilter("AuthorizationFilter", AgentAuthzBaseRoleFilter.class);
authorizationFilter.addMappingForUrlPatterns(null, false, "/service/*");
}
}
这3中方式,都是测过够写出来的。我最终使用的是 FilterRegistrationBean 方式。如果以后对顺序有要求,可以灵活的修改。v:wang13191319