概述
前言
servlet
是一种应用于服务端的,用于 Java Web 开发的,处理请求和响应输出的一种技术。
关于
Servlet 3.0
,可以先阅读 Java - servlet 3.0 这篇文章,了解相关知识,因为我们这边文章会用到Servlet 3.0
之后才提供的一些注解
概述
Filter
(过滤器):是一段可复用的代码,卡在 请求/响应
与 servlet
之间,处理请求或者修改响应。
Filter
是 servlet
容器提供的功能,实现的接口是 javax.servlet.Filter
。Filter
的使用依赖于 servlet
容器(如 Tomcat
、JBoss
等),所以只能在 web
环境中使用。
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
default void destroy() {
}
}
Servlet 环境中创建 Filter
接下来我们创建两个过滤器,来测试一下多个过滤器的执行顺序
创建一个编码过滤器 EncodingFilter
:
@WebFilter(filterName = "EncodingFilter", urlPatterns = "/*")
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init EncodingFilter...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 执行具体逻辑前
System.out.println("EncodingFilter before doFilter");
// 继续执行下一个过滤器
chain.doFilter(request, response);
// 执行具体逻辑后
System.out.println("EncodingFilter after doFilter");
}
@Override
public void destroy() {
System.out.println("destroy EncodingFilter...");
}
}
再创建一个记录请求参数和响应数据的过滤器 LoggerFilter
:
@WebFilter(filterName = "vloggerFilter", urlPatterns = "/*")
public class LoggerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init loggerFilter...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 执行具体逻辑前
System.out.println("loggerFilter before doFilter");
// 继续执行下一个过滤器
chain.doFilter(request, response);
// 执行具体逻辑后
System.out.println("loggerFilter after doFilter");
}
@Override
public void destroy() {
System.out.println("destroy loggerFilter...");
}
}
创建一个 HelloServlet
来处理请求:
@WebServlet(value = "/hello", initParams = {
@WebInitParam(name = "message", value = "hello world")
})
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello servlet 3.0");
}
}
启动 Servlet
容器,并请求 /hello
接口,输出结果:
// 启动 servlet 容器
init EncodingFilter...
init loggerFilter...
EncodingFilter before doFilter
loggerFilter before doFilter
loggerFilter after doFilter
EncodingFilter after doFilter
EncodingFilter before doFilter
loggerFilter before doFilter
loggerFilter after doFilter
EncodingFilter after doFilter
// 销毁 servlet 容器
destroy EncodingFilter...
destroy loggerFilter...
总结
从上面的输出结果中我们可以看出:
Filter
只会初始化(init)一次Filter
的执行是有顺序的- 多个过滤器之间的执行顺序,满足
先进后出
的原则(如文章开头的图所示)
因为涉及到多种注册方式,有
注解
、web.xml 配置
、运行时动态添加
等多种方式,所以关于Filter
的加载
和执行
顺序我们在之后的分析tomcat
源码的时候再讨论。
这里附上传送门:Tomcat - 分析 Servlet 中 Filter 的执行顺序
拓展
Filter
过滤器一般用于 设置字符编码
、URL级别的权限控制
、敏感词汇的过滤
、用户登录权限验证
等等,这些场景在 Spring 专栏 中关于 Spring
家族的框架源码学习中都会有具体的功能实现,比如 SpringCloudGateway 基于 Filter 实现的全局过滤器和局部过滤器
、SpringSecurity 基于 Filter 实现的认证与授权
、SpringBoot 基于 Filter 实现的全局字符编码过滤器
等等。
urlPatterns
参数中 /
和 /*
的区别(在 Servlet
规范的第 12 章中有介绍):
/
:会匹配到/login
这样的path mapping
,不会匹配到如*.jsp
之类的静态资源
/*
:会匹配到所有的资源,包括path mapping
和静态资源
最后
以上就是甜美冰棍为你收集整理的Java - servlet 三大器之过滤器 Filter前言概述Servlet 环境中创建 Filter总结拓展的全部内容,希望文章能够帮你解决Java - servlet 三大器之过滤器 Filter前言概述Servlet 环境中创建 Filter总结拓展所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复