以下所有内容均作为个人笔记,本人只是一名初学者,欢迎各位大佬指正。
前言
该篇笔记整理自瑞吉外卖项目,仅为个人总结,如有错误,还请各位大佬指正。
通过实现Filter接口中的doFilter方法,配合@WebFilter
实现拦截请求路径。
内容
为保证安全性,所有的登陆判断都需要在后端进行,返回R.successful
或者R.error
,通过其中的code
和message
判断用户是否登录。
逻辑如下:
1.过滤器配置注解
@WebFilter(filterName="拦截器类名首字母小写",urlPartten=“要拦截的路径,比如/*”)
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
2.实现Filter接口,重写doFilter方法
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//放行逻辑
}
参数:
-
ServletRequest servletRequest
:-
这是一个表示HTTP请求的接口,它提供了对请求的各种信息的访问,如请求参数、头部信息、URI等。在
doFilter
方法中,可以使用ServletRequest
来获取关于客户端请求的信息,以便进行适当的处理。
-
-
ServletResponse servletResponse
:-
这是一个表示HTTP响应的接口,它提供了向客户端发送响应的方法,如设置响应状态码、响应头部、响应内容等。在
doFilter
方法中,可以使用ServletResponse
来操作和定制服务器响应。
-
-
FilterChain filterChain
:-
FilterChain
用于在过滤器链中调用下一个过滤器,或者调用目标资源。过滤器链中的所有过滤器都会按照它们在web.xml
文件或注解中的声明顺序执行。 -
在
doFilter
方法中,可以调用filterChain.doFilter(servletRequest, servletResponse)
来继续执行下一个过滤器或目标资源。
-
3.定义路径匹配与需放行url
AntPathMatcher
是 Spring Framework 提供的一个路径匹配器工具类。它用于执行基于 Ant 样式的路径模式匹配,类似于 Ant 构建工具中用于指定文件和目录的匹配模式。例如,/user/*/profile
可以匹配 /user/123/profile
。
//路径匹配器,支持通配符,可以匹配通配符。
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
添加需要放行的地址
//定义不需要处理的请求路径,无法直接放行带有【通配符】的请求路径,需要和AntPathMatcher配合使用
String[] urls = new String[]{
//放行地址,例如
"/employ/login",
};
4.获取请求的uri地址,判断是否需要放行。
//1.获取本次请求的uri
String requestURI = request.getRequestURI();
判断函数
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return 需要放行:true, 否则:false
*/
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match) {
return true;
}
}
return false;
}
5.执行拦截(非拦截)逻辑
//3.如果不需要处理,则直接放行
if(check) {
filterChain.doFilter(request, response);
return;
}
//4.判断登录状态,如果已登录,则直接放行
if(request.getSession().getAttribute("employee") != null) {
filterChain.doFilter(request, response);
return;
}
//5.如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
注意:报错No mapping for Get /employee/page可能是因为过滤器没有扫描,在启动类中加个@ServletCompomentScan
总结
完整代码示例
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
//@Configuration
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符,可以匹配通配符。
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1.获取本次请求的uri
String requestURI = request.getRequestURI();
//定义不需要处理的请求路径
String[] urls = new String[]{
"/employee/login",
"/common/**"
};
//2.判断本次请求是否需要处理
boolean check = check(urls,requestURI);
//3.如果不需要处理,则直接放行
if(check) {
filterChain.doFilter(request, response);
return;
}
//4.判断登录状态,如果已登录,则直接放行
if(request.getSession().getAttribute("employee") != null) {
Long id = (Long) request.getSession().getAttribute("employee");
BaseContext.setCurrentId(id);
filterChain.doFilter(request, response);
return;
}
//5.如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return 需要放行:true, 否则:false
*/
public boolean check(String[] urls, String requestURI) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match) {
return true;
}
}
return false;
}
}