目录
万能图
过滤器自我理解
案例 实现Filter 接口
配置文件 web.xml
将过滤器映射到 servlet
用处
拦截器 手写案例
重写 preHandle() 方法 拦截处理
重写 postHandle() 方法 后处理
重写 afterHandle() 方法 完成处理
代码
如何配置拦截器
万能图
还是看一下这张图 太重要了
过滤器是在请求进入 Servlet 容器前对请求进行
预处理 过滤 拦截等一系列操作
过滤器自我理解
过滤器虽然是 HTTP 请求进入 web 服务器后第一个经过的地方
但他是基于 Java Servlet 规范实现的
Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
案例 实现Filter 接口
//导入必需的 java 库
import javax.servlet.*;
import java.util.*;
//实现 Filter 类
public class LogFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
// 获取初始化参数
String site = config.getInitParameter("Site");
// 输出初始化参数
System.out.println("网站名称: " + site);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
// 输出站点名称
System.out.println("站点网址:http://www.runoob.com");
// 把请求传回过滤链
chain.doFilter(request,response);
}
public void destroy( ){
/* 在 Filter 实例被 Web 容器从服务移除之前调用 */
}
}
配置文件 web.xml
定义过滤器,然后映射到一个 URL 或 Servlet,这与定义 Servlet,然后映射到一个 URL 模式方式大致相同。在部署描述符文件 web.xml 中为 filter 标签创建下面的条目:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.runoob.test.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>菜鸟教程</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<!-- 类名 -->
<servlet-name>DisplayHeader</servlet-name>
<!-- 所在的包 -->
<servlet-class>com.runoob.test.DisplayHeader</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayHeader</servlet-name>
<!-- 访问的网址 -->
<url-pattern>/TomcatTest/DisplayHeader</url-pattern>
</servlet-mapping>
</web-app>
将过滤器映射到 servlet
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.runoob.test.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>菜鸟教程</param-value>
</init-param>
</filter>
通过注解也可以
在 LogFilter 上加上@ WebFilter 注解
然后再启动类里面用@ ServletComponentScan 注解 指定到过滤器类也行
用处
拦截器 手写案例
路径拦截器
手写了一个案例
是当当请求进入 web 服务器后 在到达 controller 之前
校验是否可以访问路径
首先我们创建一个类 实现 HandlerInterceptor 接口
重写 preHandle() 方法 拦截处理
- 首先排除不需要拦截的路径 遍历数组 元素相同直接返回 ture
- 接着检查登录状态 从 HttpSession 里面去拿
- 根据登录状态往 response(HttpServletResponse) 里面塞数据返回
- 接着可以校验权限级别 验证 token 的有效期等
重写 postHandle() 方法 后处理
在 request 里面记录一些东西 请求处理时间 响应头
等到请求前往 controller 后会进行处理
重写 afterHandle() 方法 完成处理
可以进行日志记录 之类的
代码
import HandlerInterceptor.HandlerInterceptor;
import org.springframework.util.AntPathMatcher;
import javax.servlet.http.*;
public final class LoginInterceptor implements HandlerInterceptor {
// 不需要拦截的路径
private static final String[] EXCLUDE_PATHS = {
"/user/login",
"/user/register",
"/static/**",
"/error"
};
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String requestURI = request.getRequestURI();
// 1. 排除不需要拦截的路径 [8]()
for (String path : EXCLUDE_PATHS) {
if (new AntPathMatcher().match(path, requestURI)) {
return true;
}
}
// 2. 检查登录状态 [7]()
HttpSession session = request.getSession();
Object userInfo = session.getAttribute("LOGIN_USER");
// 3. 当用户未登录时
if (userInfo == null) {
// 根据请求类型返回不同响应 [3]()
if (isAjaxRequest(request)) {
response.setContentType("application/json");
response.getWriter().write("{\"code\":401, \"msg\":\"未认证\"}");
} else {
response.sendRedirect("/login");
}
return false;
}
// 4. 可扩展的权限验证逻辑 [15]()
// 例如验证token有效期、权限级别等
return true;
}
// 后处理
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// 记录请求处理时间、修改响应头等 [10]()
long startTime = (Long) request.getAttribute("requestStartTime");
long executeTime = System.currentTimeMillis() - startTime;
request.setAttribute("executeTime", executeTime);
}
// 完成处理
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 资源清理、异常记录等 [7]()
if (ex != null) {
log.error("Request processing error: " + request.getRequestURI(), ex);
}
}
// 判断是否为Ajax请求
private boolean isAjaxRequest(HttpServletRequest request) {
return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
}
}
如何配置拦截器
跟过滤器一个道理
也是两种配置方式
一个是基于配置文件 一个是基于注解