上一篇咱们学习了 spring boot 利用Controller响应数据与响应页面。 通常的Web开发使用 Controller 基本上能够完成大部分需求,可是有的时候咱们仍是会用到 Servlet、Filter、Listener 等等。html
在spring boot中添加本身的Servlet、Filter、Listener有两种方法java
- 代码注册: 经过ServletRegistrationBean、 FilterRegistrationBean 和ServletListenerRegistrationBean 得到控制。
- 注解注册: 在SpringBootApplication 上使用@ServletComponentScan注解后,Servlet、Filter、Listener 能够直接经过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其余代码。
spring boot 中注册servlet
代码注册
- 建立Servlet类:AaServlet.java。
public class AaServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet"); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost()"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<h1>AaServlet</h1>"); } }
- 经过ServletRegistrationBean注册。
//Project2Application.java @Bean public ServletRegistrationBean AaServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean(new AaServlet()); registration.addUrlMappings("/a"); return registration; }
- 运行测试。
访问:http://localhost:8080/aspring

注解注册
- 建立Servlet类:BbServlet.java。
@WebServlet(urlPatterns = "/b") public class BbServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet"); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost()"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<h1>BbServlet</h1>"); } }
- 添加注解@ServletComponentScan。
@ServletComponentScan @SpringBootApplication public class Project2Application { public static void main(String[] args) { SpringApplication.run(Project2Application.class, args); } @Bean public ServletRegistrationBean AaServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean(new AaServlet()); registration.addUrlMappings("/a"); return registration; } }
- 运行测试。
访问:http://localhost:8080/b浏览器

filter 和 listener的注册和servlet同样。这里就很少说了。app
接下来讲一下拦截器。ide
自定义拦截器
Spring提供了HandlerInterceptor(拦截器)。它的功能跟过滤器相似,可是提供更精细的的控制能力:在request被响应以前、request被响应以后、视图渲染以前以及request所有结束以后。咱们不能经过拦截器修改request内容,可是能够经过抛出异常(或者返回false)来暂停request的执行。oop
spring boot提供了一些拦截器,咱们能够直接拿来使用,好比:post
- ConversionServiceExposingInterceptor
- CorsInterceptor
- LocaleChangeInterceptor
- PathExposingHandlerInterceptor
- ResourceUrlProviderExposingInterceptor
- ThemeChangeInterceptor
- UriTemplateVariablesHandlerInterceptor
- UserRoleAuthorizationInterceptor
咱们也能够本身定义拦截器,定义拦截器的步骤大体分为:学习
一、建立咱们本身的拦截器类并实现 HandlerInterceptor 接口。
二、建立一个Java类继承WebMvcConfigurerAdapter,并重写addInterceptors 方法。
三、实例化咱们自定义的拦截器,而后将对像手动添加到拦截器链中(在addInterceptors方法中添加)。测试
咱们来亲自试一下:
- 建立咱们本身的拦截器
//MyInterceptor2 public class MyInterceptor1 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor1==========>在请求处理以前进行调用(Controller方法调用以前)"); return true;// 只有返回true才会继续向下执行,返回false取消当前请求 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor1==========>请求处理以后进行调用,可是在视图被渲染以前(Controller方法调用以后)"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor1==========>在整个请求结束以后被调用,也就是在DispatcherServlet 渲染了对应的视图以后执行(主要是用于进行资源清理工做)"); } }
//MyInterceptor2 public class MyInterceptor2 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor2==========>在请求处理以前进行调用(Controller方法调用以前)"); return true;// 只有返回true才会继续向下执行,返回false取消当前请求 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor2==========>请求处理以后进行调用,可是在视图被渲染以前(Controller方法调用以后)"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor2==========>在整个请求结束以后被调用,也就是在DispatcherServlet 渲染了对应的视图以后执行(主要是用于进行资源清理工做)"); } }
建立一个Java类继承WebMvcConfigurerAdapter,并重写addInterceptors 方法,添加拦截器。
//MyWebAppConfigurer @Configuration public class MyWebAppConfigurer extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { // 多个拦截器组成一个拦截器链 // addPathPatterns 用于添加拦截规则 // excludePathPatterns 用户排除拦截 registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**"); registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**"); super.addInterceptors(registry); } }
测试:运行项目,随便访问一个路径,好比http://localhost:8080/test
浏览器会报错,不用管,看控制台。

拦截器已经起做用了。
值得注意的是:只有通过DispatcherServlet 的请求,才会走拦截器链,咱们自定义的Servlet 请求是不会被拦截的,好比咱们自定义的Servlet地址是不会被拦截器拦截的。
可是过滤器不一样。无论是属于哪一个Servlet 只要复合过滤器的过滤规则,过滤器都会拦截。
本篇文章就先介绍到这里,若是哪里讲的不明白,请及时与我联系。
参考文章:Spring Boot 拦截器
做者:cleverfan连接:https://www.jianshu.com/p/fba5c0fd09bb來源:简书著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。