一、项目中加入自定义filter实现Filter接口
1、写自定义Filter类
public class SessionFilter implements Filter{
public FilterConfig config;
private static Map<String, String> authMap = new HashMap<>();
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 获取request
HttpServletRequest hrequest = (HttpServletRequest) request;
// 获取session
HttpSession session = hrequest.getSession();
// 能获取response数据,类包装了ServletResponse,可以进行IO操作,返回数据
HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
// 过滤资源后缀参数,已经在web.xml中配置
String includeStrings = config.getInitParameter("excludeStrings");
// 没有登陆转向页面
String loginPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");
// 过滤器是否有效
String disabletestfilter = config.getInitParameter("disabletestfilter");
// 过滤器无效,直接跳过
if (disabletestfilter.toUpperCase().equals("Y")) {
chain.doFilter(request, response);
return;
}
String requestUri = hrequest.getServletPath();
if ("/".equals(requestUri)) {
chain.doFilter(request, response);
return;
}
// 只对指定过滤参数后缀进行过滤,或者请求地址在白名单内
String[] includeList = includeStrings.split(";");
if (isContains(requestUri, includeList) || isFilter(requestUri)) {
chain.doFilter(request, response);
return;
}
// 判断session中是否有用户登录,如果有过滤
String user = (String) session.getAttribute("user_session");
if (user != null) {
chain.doFilter(request, response);
return;
}
// 以上条件都不符合,跳转到登录界面
wrapper.sendRedirect(loginPath);
return;
}
@Override
public void destroy() {
this.config = null;
}
// 判断请求是否在请求 白名单内
private static boolean isFilter(String url) {
if (authMap.isEmpty()) {
authMap = cacheProperties("auth");
if (authMap.isEmpty()) {
return true;
}
}
for (String key : authMap.keySet()) {
if (key.contains("**")) {
key = key.replace("/**", "");
if (url.startsWith(key)) {
return true;
}
} else if (key.equals(url)) {
return true;
}
}
return false;
}
public static boolean isContains(String container, String[] regx) {
for (int i = 0; i < regx.length; i++) {
if (container.indexOf(regx[i]) != -1) {
return true;
}
}
return false;
}
// 读取配置文件内容的方法
public static Map<String, String> cacheProperties(String propName) {
Map<String, String> map = new HashMap<String, String>();
ClassPathResource cp = new ClassPathResource(propName + ".properties");
Properties properties = new Properties();
try {
properties.load(cp.getInputStream());
} catch (IOException e) {
throw new RuntimeException("load "+propName+".properties error!");
}
for (Iterator<?> its = properties.keySet().iterator(); its.hasNext();) {
String zkey = (String) its.next();
map.put(zkey, properties.getProperty(zkey).trim());
}
return map;
}
}
在类中注释的很清楚了,读者如有不懂请留言咨询。
2、白名单配置
#白名单配置,可自行扩展
/common/** = anon
/login = anon
/logon = anno
二、web.xml中配置自定义filter
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>com.test.filter.SessionFilter</filter-class> <!-- 自定义filter所在包路径 -->
<init-param>
<param-name>excludeStrings</param-name>
<param-value>.css;.js;.jpg;.png</param-value>
</init-param>
<init-param>
<param-name>redirectPath</param-name>
<param-value>/login</param-value>
</init-param>
<init-param>
<param-name>disabletestfilter</param-name>
<param-value>N</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
三、测试结果
我们在用户登录时,将用户信息存到session中:
@RequestMapping("logon")
public String logon(HttpServletRequest request,String userName,String password) {
if (userName != null) {
// 将用户存到session里去
HttpSession session = request.getSession();
session.setAttribute("user_session", userName);
return "index";
}
return "login";
}
1、启动项目跳转到登录页面,当我们不登录直接访问/user/hello这个地址时,我们发现浏览器会自动跳转到登录界面。当我们登录之后,再访问/user/hello时,能跳转到对应的页面。
2、白名单测试,我们把/user/hello加入到我们的白名单中,没有登录访问/user/hello这个地址,我们会发现 直接跳转至相应页面。
至此,自定义过滤器实现完成,过滤器实现的功能如下:
(1)登录权限控制
(2)登录白名单
(3)对一些静态资源文件过滤
欢迎广大读者留言评论。