监听器Listener,它是实现了javax.servlet.XXXListener接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的中止而销毁。主要做用是:作一些初始化的内容添加工做、设置一些基本的内容、好比一些参数或者是一些固定的对象等等。java
在javax.servlet.XXXListener接口中定义了2种方法:web
void contextInitialized(ServletContextEvent sce) 监听器的初始化spring
void contextDestroyed(ServletContextEvent sce) 监听器销毁json
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、作一些业务逻辑判断等。其工做原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就能够对请求或响应(Request、Response)统一设置编码,简化操做;同时还能够进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工做,它是随你的web应用启动而启动的,只初始化一次,之后就能够拦截相关的请求,只有当你的web应用中止或从新部署的时候才能销毁。服务器
在javax.servlet.Filter接口中定义了3个方法:session
void init(FilterConfig filterConfig) 用于完成过滤器的初始化app
void destroy() 用于过滤器销毁前,完成某些资源的回收ide
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 实现过滤功能,该方法对每一个请求增长额外的处理工具
拦截器主要是用在插件上,扩展件上好比spring、struts2等有点相似面向切片的技术,它是基于java反射机制。定义拦截器: 实现HandlerInterceptor 接口,或者继承实现了HandlerInterceptor 接口的类(经常使用) 。post
过滤器(Filter):当你有一堆东西的时候,你只但愿选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。 对请求起到过滤的做用,它在监听器以后,做用在servlet以前,对请求进行过滤。
拦截器(Interceptor):在一个流程正在进行的时候,你但愿干预它的进展,甚至终止它进行,这是拦截器作的事情。
监听器(Listener):当一个事件发生的时候,你但愿得到这个事件发生的详细信息,而并不想干预这个事件自己的进程,这就要用到监听器。对项目起到监听的做用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化 。对请求和返回进行拦截,它做用在servlet的内部 。
它们之间的关系,能够用一张图来表示:
使用原则
对整个流程清楚以后,而后就是各自的使用,在使用以前应该有一个使用规则,为何这个说,由于有些功能好比判断用户是否登陆,既能够用过滤器,也能够用拦截器,用哪个才是合理的呢?那么若是有一个原则,使用起来就会更加合理。实际上这个原则是有的:把整个项目的流程比做一条河,那么监听器的做用就是可以听到河流里的全部声音,过滤器就是可以过滤出其中的鱼,而拦截器则是拦截其中的部分鱼,而且做标记。因此当须要监听到项目中的一些信息,而且不须要对流程作更改时,用监听器;当须要过滤掉其中的部分信息,只留一部分时,就用过滤器;当须要对其流程进行更改,作相关的记录时用拦截器。
代码注册方式
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); } }
代码注册方式
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); } }
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); } }