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容器。在實現上基於函數回調,可以對幾乎所有請求進行過濾,但是缺點是一個過濾器實例只能在容器初始化時調用一次。使用過濾器的目的是用來做一些過濾操作,獲取我們想要獲取的數據等,過濾器通過我們設定好的順序,依次執行,最後執行請求的接口。