下面是详细讲解“聊聊java 过滤器、监听器、拦截器的区别(终结篇)”的完整攻略。
什么是过滤器、监听器和拦截器?
在 Java Web 开发中,过滤器(Filter)、监听器(Listener)、拦截器(Interceptor)都是用来对 HTTP 请求进行处理和过滤的技术手段。
过滤器(Filter)
过滤器(Filter)是在 Servlet 中用来对请求和响应进行预处理和后处理的简单对象,用于统一修改请求/响应属性或处理请求/响应。Filter 通常用于对请求进行过滤处理,比如编码转换、HTTP 认证等。
监听器(Listener)
监听器(Listener)是在 Servlet 中用来监听 Web 应用程序中某些对象和事件状态的接口,以触发相应的事件处理器对其作出响应。比如,我们可以监听会话的创建和销毁事件,对用户的会话进行管理。
拦截器(Interceptor)
拦截器(Interceptor)是 Spring Framework 提供的,是一种更强大的对请求的拦截和修改的机制,也用于统一地修改请求/响应属性或处理请求/响应,但比 Filter 更加强大。拦截器具有链式的特点,可以自由控制拦截顺序,也可以中断后面的拦截器或处理器。拦截器可以用于各种场景,比如拦截非法请求、记录请求日志、性能监控等。
过滤器、监听器、拦截器的区别
处理范围不同
过滤器是处理请求和响应,监听器是监听对象、资源、事件等的变化,拦截器是在控制器(Controller)前后进行拦截,处理请求和响应。
触发时机不同
过滤器是在请求被 Servlet 前处理,响应处理结束后才被调用,如下图:
---------- ---------- ----------
Request | Filter1 |---->| Filter2 |---->| Filter3 |---->| Servlet |
---------- ---------- ----------
---------- ---------- ----------
Response| Filter3 |<----| Filter2 |<----| Filter1 |<----| Servlet |
---------- ---------- ----------
监听器是在对象的生命周期中监听对象的某些状态,如下图:
------------------
Web Container | Object | Event |
------------------
| /\ | ^
| | | |
| | | |
v | | |
-------------------
Application | Listener |
-------------------
拦截器是在请求到达控制器之前或者响应返回浏览器之前进行拦截或者修改,如下图:
------------
Inbound --->|Interceptors|---+
------------ |
| |Before the
| |Controller
v |
------------
--->| Controller |
------------
| |
v |After the
------------ |Controller
|Interceptors|
-------------
| |
v Outbound
------------
<---|Interceptors|<---
------------
配置方式不同
Filter 配置在 web.xml 中:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Listener 配置在 web.xml 中:
<listener>
<listener-class>com.example.MyListener</listener-class>
</listener>
Interceptor 配置在 Spring 的配置文件中:
<mvc:interceptors>
<bean class="com.example.MyInterceptor"/>
</mvc:interceptors>
示例说明
示例 1:使用过滤器统一处理编码问题
在很多 Web 应用中,中文字符集的编码很容易出现问题,如果没能正确处理会出现乱码问题,这时可以使用过滤器来统一处理编码问题,比如下面的代码:
public class EncodingFilter implements Filter {
private String encoding;
public void init(FilterConfig filterConfig) throws ServletException {
encoding = filterConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
response.setContentType("text/html;charset=" + encoding);
chain.doFilter(request, response);
}
public void destroy() {
}
}
在 web.xml 中配置过滤器:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>com.example.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这样,在所有的请求中,请求参数的编码方式都会被统一设置成 UTF-8。
示例 2:使用拦截器记录请求日志
在许多场景中,需要记录请求日志,比如,记录请求的 URL、请求方法、请求参数、请求时间等,这时候我们可以使用拦截器来实现,比如下面的代码:
public class LogInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info("请求: {}, 方法: {}", request.getRequestURL(), request.getMethod());
logger.info("IP地址: {}", request.getRemoteAddr());
logger.info("请求参数: {}", JSONObject.toJSONString(request.getParameterMap()));
logger.info("请求时间: {}", LocalDateTime.now());
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
在 Spring 的配置文件中配置拦截器:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.example.LogInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
这样,在所有的请求前,都会先记录请求日志,并打印到日志文件中。
以上就是关于“聊聊java 过滤器、监听器、拦截器的区别(终结篇)”的全部内容。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:聊聊java 过滤器、监听器、拦截器的区别(终结篇) - Python技术站