springboot 的过滤器实现主要有两个类
1.过滤器注册类
package com.newland.common.autoconfigure;
import com.newland.common.filter.SessionFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.DispatcherType;
/**
* 登录配置加载
* @author
*
*/
@Configuration
public class SessionAutoConfiguration {
@Bean
public FilterRegistrationBean sessionFilter() {
//新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加我们写好的过滤器
registration.setFilter( new SessionFilter());
// 设置过滤器的URL模式
registration.setDispatcherTypes(DispatcherType.REQUEST);
//匹配路径
//List<String> urlPatterns = new ArrayList<>();
//urlPatterns.add("/*");
//registration.setUrlPatterns(urlPatterns);
registration.addUrlPatterns("/web/*");
//不过滤的路径,俗称白名单
registration.addInitParameter("exclusions","/web/login,/ecommerce/register");
//设置过滤器顺序
registration.setOrder(1);
return registration;
}
}
2.上面就是个一过滤器注册类,下面这个类才是过滤器的实现类,注册SessionFilter 这个过滤器
package com.newland.common.filter;
import com.newland.ecommerce.model.entity.SysUserDO;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;
@WebFilter(filterName = "sessionFilter")
public class SessionFilter implements Filter{
//标示符:表示当前用户未登录(可根据自己项目需要改为json样式)
String NO_LOGIN = "您还未登录";
public static final String PARAM_NAME_EXCLUSIONS = "exclusions";
//不需要登录就可以访问的路径(比如:注册登录等)
private Set<String> excludesPattern;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//这里是注册类中添加的白名单,转为Set集合
String param = filterConfig.getInitParameter(PARAM_NAME_EXCLUSIONS);
if (param != null && param.trim().length() != 0) {
this.excludesPattern = new HashSet(Arrays.asList(param.split("\\s*,\\s*")));
}
}
@SuppressWarnings("unlikely-arg-type")
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession(false);
String uri = request.getRequestURI();
//下面这行代码是业务需求,获取请求参数
String supplierCode = request.getParameter("supplierCode");
//判断是否需要过滤,白名单中的路径不需要过滤,可以自由发挥
boolean needFilter = isNeedFilter(uri);
if (!needFilter) { //不需要过滤直接传给下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
} else { //需要过滤器
// session中包含user对象,则是登录状态
if(session!=null&&session.getAttribute("sysUser") != null){
//这里获取用户的权限,这个可以参考我的springboot整合shiro的数据库表设计
List<Map<String,String>> userPermission = (List<Map<String, String>>) session.getAttribute("userPermission");
SysUserDO sysUser = (SysUserDO) session.getAttribute("sysUser");
//检查当前用户是否有权限
if(userPermission != null && userPermission.size() != 0) {
for(Map<String,String> up : userPermission) {
if(uri.startsWith(up.get("resourceUrl"))) {
if(3 == sysUser.getType()) {
if(supplierCode != null) {
if(!supplierCode.equals(sysUser.getOwnedSupplierCode())) {
response.sendRedirect(request.getContextPath()+"/web/index");
return;
}
}
}
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
}
//重定向
response.sendRedirect(request.getContextPath()+"/unPermission");
}else{
String requestType = request.getHeader("X-Requested-With");
//判断是否是ajax请求
if(requestType!=null && "XMLHttpRequest".equals(requestType)){
response.getWriter().write(this.NO_LOGIN);
}else{
//重定向到登录页(需要在static文件夹下建立此html文件)
response.sendRedirect(request.getContextPath()+"/login");
}
return;
}
}
}
/**
* 是否需要过滤
* @param uri
* @return
*/
public boolean isNeedFilter(String uri) {
for (String includeUrl : excludesPattern) {
if(includeUrl.contains("*")) {
if(uri.startsWith(includeUrl.substring(0, includeUrl.length() - 1))) {
return false;
}
}else {
if(includeUrl.equals(uri)) {
return false;
}
}
}
return true;
}
@Override
public void destroy() {
}
}
3.过滤器依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据等,过滤器通过我们设定好的顺序,依次执行,最后执行请求的接口。