1 监听器、过滤器和拦截器
1.1 监听器
监听器Listener,它是实现了javax.servlet.XXXListener接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。
在javax.servlet.XXXListener接口中定义了2种方法:
void contextInitialized(ServletContextEvent sce) 监听器的初始化
void contextDestroyed(ServletContextEvent sce) 监听器销毁
1.2 过滤器
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可以进行逻辑判断,如用户是否已经登录、有没有权限访问该页面等等工作,它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关的请求,只有当你的web应用停止或重新部署的时候才能销毁。
在javax.servlet.Filter接口中定义了3个方法:
void init(FilterConfig filterConfig) 用于完成过滤器的初始化
void destroy() 用于过滤器销毁前,完成某些资源的回收
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 实现过滤功能,该方法对每个请求增加额外的处理
1.3 拦截器
拦截器主要是用在插件上,扩展件上比如spring、struts2等有点类似面向切片的技术,它是基于java反射机制。定义拦截器: 实现HandlerInterceptor 接口,或者继承实现了HandlerInterceptor 接口的类(常用) 。
2 监听器、过滤器和拦截器的关系及区别
过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。 对请求起到过滤的作用,它在监听器之后,作用在servlet之前,对请求进行过滤。
拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。
监听器(Listener):当一个事件发生的时候,你希望获得这个事件发生的详细信息,而并不想干预这个事件本身的进程,这就要用到监听器。对项目起到监听的作用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化 。对请求和返回进行拦截,它作用在servlet的内部 。
它们之间的关系,可以用一张图来表示:
使用原则
对整个流程清楚之后,然后就是各自的使用,在使用之前应该有一个使用规则,为什么这个说,因为有些功能比如判断用户是否登录,既可以用过滤器,也可以用拦截器,用哪一个才是合理的呢?那么如果有一个原则,使用起来就会更加合理。实际上这个原则是有的:把整个项目的流程比作一条河,那么监听器的作用就是能够听到河流里的所有声音,过滤器就是能够过滤出其中的鱼,而拦截器则是拦截其中的部分鱼,并且作标记。所以当需要监听到项目中的一些信息,并且不需要对流程做更改时,用监听器;当需要过滤掉其中的部分信息,只留一部分时,就用过滤器;当需要对其流程进行更改,做相关的记录时用拦截器。
3 监听器实现过程
代码注册方式
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class IndexListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("IndexListener contextDestroyed method");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("IndexListener contextInitialized method");
}
}
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean(){
ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean();
servletListenerRegistrationBean.setListener(new IndexListener());
return servletListenerRegistrationBean;
}
注解方式
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class IndexListener2 implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("IndexListener2 contextDestroyed method");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("IndexListener2 contextInitialized method");
}
}
@SpringBootApplication
@ServletComponentScan
public class SpringBootSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSimpleApplication.class, args);
}
}
4 过滤器实现过程
代码注册方式
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (......) {
......
response.getWriter().write(writeValueAsString);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
TestFilter testFilter = new TestFilter();
registrationBean.setFilter(testFilter);
List<String> urlPatterns = new ArrayList<String>();
urlPatterns.add("/service/extract/json/*");
registrationBean.setUrlPatterns(urlPatterns);
return registrationBean;
}
注解方式
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* 实现javax.servlet.Filter,覆盖其三个方法
* @author Administrator
*
*/
@WebFilter(filterName="testFilter",urlPatterns="/*")
public class TestFilter implements Filter{
@Override
public void destroy() {
System.out.println("TestFilter过滤器销毁");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("TestFilter指定过滤器操作......");
//执行操作后必须doFilter
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("TestFilter初始化......");
}
}
@SpringBootApplication
@ServletComponentScan
public class SpringBootSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSimpleApplication.class, args);
}
}
5 拦截器实现过程
- 创建自己的拦截器实现HandlerInterceptor接口
- 创建自己的拦截器链,继承WebMvcConfigurerAdapter类,重写addInterceptors方法。
- 实例化自己的拦截器,并加入到拦截器链中。
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class CustomInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object,
Exception exception) throws Exception {
//在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
System.out.println("3. 整个请求结束之后被调用......CustomInterceptor1......");
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView view)
throws Exception {
// 请求处理之后进行调用,但是在视图被渲染之前
System.out.println("2. 请求处理之后进行调用,但是在视图被渲染之前......CustomInterceptor1......");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
// 在请求处理之前进行调用
System.out.println("1. 在请求处理之前进行调用......CustomInterceptor1......");
// 只有返回true才会继续向下执行,返回false取消当前请求
return true;
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.example.Interceptor.CustomInterceptor;
import com.example.Interceptor.CustomInterceptor2;
/**
* 继承WebMvcConfigurerAdapter,复写addInterceptors方法
* @author Administrator
*
*/
@Configuration
public class WebAdapter extends WebMvcConfigurerAdapter{
/**
* 主要方法说明:
* addPathPatterns 用于添加拦截规则
* excludePathPatterns 用于排除拦截
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//众多的拦截器组成了一个拦截器链
registry.addInterceptor(new CustomInterceptor()).addPathPatterns("/*");
super.addInterceptors(registry);
}
}
来源:oschina
链接:https://my.oschina.net/u/570654/blog/1557918