【Java EE(Java Web)】期末复习 知识点总结 第五节 Filter
Filter
1.概念与作用
(1)Servlet 的核心是 “请求处理与流程控制”,但 Web 应用中存在大量通用功能(如权限校验、日志记录、字符编码转换),若直接在 Servlet 中实现这些功能,会导致代码冗余、耦合严重。Filter 可拦截请求 / 响应:在请求到达 Servlet 之前(预处理)或响应返回客户端之后(后处理)执行通用逻辑,将通用功能从 Servlet 中抽离(类似 Spring 框架的 AOP)为独立 Filter,通过配置即可全局生效,无需修改业务代码。
(2)Filter 是 Servlet2.3 规范新特性。Filter 拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。注意:Filter 不是 Servlet,它只是 Servlet 接收请求前的预处理器。
(3)Filter 与 Servlet 的关联由 Web 应用的配置描述文件来明确
2.Filter 主要应用场景
(1)访问特定资源(Web 页、JSP 页、Servlet)时的身份验证,禁止非法用户访问
(2)访问资源的记录跟踪。
(3)字符编码转换
3.核心实现(1个接口,3个方法)
一个 Filter 必须实现
javax.Servlet.Filter 接口
方法1:doFilter (ServletRequest, ServletResponse, FilterChain):用来实现过滤行为的方法。引入的 FilterChain 对象提供了后续 Filter 所要调用的信息
方法2:init(FilterConfig)
方法3:destroy()
- 示例
@WebFilter("/*")
public class SimpleFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 1. 处理请求前的逻辑
System.out.println("请求到达");
// 2. 必须调用这一行!
chain.doFilter(request, response);// 放行到下一个 Filter
// 3. 处理响应后的逻辑
System.out.println("响应返回");
}
}
4.执行流程
请求流程:浏览器 -> Filter1(Before -> doFilter ())-> Filter2(Before -> doFilter ())-> Servlet -> Filter2(After)-> Filter1(After)-> 响应
总结:
必须实现 Filter 接口
必须调用 chain.doFilter()(否则请求卡住)
常用注解 @WebFilter 配置
处理请求在 chain.doFilter() 之前
处理响应在 chain.doFilter() 之后
5.配置
配置步骤
新建 Filter、指定过滤对象(可以是 URL 模式或逻辑名称),将信息添加到部署描述符(web.xml)
配置参数(新建 Filter 时需填写)
Name:如 TimingFilter、TimeTrackFilter
Description
Initialization parameters(Name、Value、Description)
Filter mappings:URL Pattern / Servlet Name、Dispatchers
Asynchronous Support
web.xml 配置片段
<filter>
<filter-name>TimeTrackFilter</filter-name>
<filter-class>com.servlet.TimeTrackFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>TimeTrackFilter</filter-name>
<url-pattern>/Main</url-pattern>
</filter-mapping>
6.Filter 与 SSM 框架的关联
(1)SSM 框架可直接使用 Filter 解决通用问题,也允许通过自定义 Filter 扩展业务功能,二者协同实现请求全链路处理
(2)Spring 框架为简化开发,提供了多个开箱即用的 Filter,开发者可直接配置到 web.xml 或通过注解启用,无需重复编码。例如 Spring 提供的基础 Filter:CharacterEncodingFilter 可以统一请求 / 响应编码(解决中文乱码)
7.常用filter
7.1字符编码过滤器
@WebFilter("/*")
public class EncodingFilter implements Filter {
private String encoding = "UTF-8";
@Override
public void init(FilterConfig config) {
// 从配置读取编码
String configEncoding = config.getInitParameter("encoding");
if (configEncoding != null) {
this.encoding = configEncoding;
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 1. 设置请求编码(解决中文乱码)
request.setCharacterEncoding(encoding);
// 2. 设置响应编码
response.setCharacterEncoding(encoding);
response.setContentType("text/html;charset=" + encoding);
// 3. 放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
// 清理资源(如果有的话)
}
}
7.2登录检查过滤器
@WebFilter({"/user/*", "/admin/*", "/cart/*"}) // 只过滤需要登录的路径
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
// 转换为 HttpServlet 对象
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 获取 session
HttpSession session = request.getSession(false);
// 检查是否已登录
if (session == null || session.getAttribute("user") == null) {
// 未登录,重定向到登录页
response.sendRedirect(request.getContextPath() + "/login.jsp");
return; // 重要:不调用 chain.doFilter()
}
// 已登录,放行
chain.doFilter(request, response);
}
}
更多推荐

所有评论(0)