ToB企服应用市场:ToB评测及商务社交产业平台

标题: 过滤器、监听器、拦截器 [打印本页]

作者: 卖不甜枣    时间: 2024-7-19 08:53
标题: 过滤器、监听器、拦截器
目录

一、 主要内容
二、 过滤器
2.1 介绍
2.2 实现
MyFilter01
MyFilter02
MyServlet01
MyServlet02
2.3 说明
2.4 实行顺序
1. 利用 web.xml
2. 利用注解和@Order
3. 利用FilterRegistrationBean
2.5字符乱码
三、监听器
3.1介绍
3.2实现
3.3在线人数统计
OnlineListener
OnlineServlet2
四、拦截器
4.1介绍
4.2实现方式
1.实现HandlerInterceptor接口
2.实现WebRequestInterceptor接口
3.继续HandlerInterceptorAdapter类
4.注册拦截器
4.3解决的标题
4.4与Spring Boot的集成
4.4实行顺序控制
4.5身份验证明例
步调一:创建拦截器
步调二:配置拦截器
步调三:测试
注意事项
五、过滤器和拦截器区别 (面试常问)
六、如何理解"拦截器只能拦截部分web哀求"
1.拦截器的作用范围
2.为什么拦截器不能拦截全部Web哀求?
3.如何拦截全部Web哀求?



一、 主要内容

过滤器(Filter)监听器(Listener)拦截器(Interceptor)关注点web哀求系统级别参数、对象Action(部分Web哀求)实现方式函数回调事件Java反射机制应用场景设置字符编码统计网站在线人数拦截未登任命户URL级别的权限访问控制清晰逾期session审计日志过滤敏感词汇压缩响应信息是否依赖Servlet容器是否Servlet提供的支持Filter接口ServletRequestListener HttpSessionListener ServletContextListenerSpring提供的支持HandlerInterceptor WebRequestInterceptor HandlerInterceptorAdapter级别系统级别系统级别非系统级别
二、 过滤器

2.1 介绍




若是一个过滤器链:先配置先实行(哀求时的实行顺序);响应时:以相反的顺序实行
   在 HttpServletRequest 到达 Servlet 之前拦截客户的HttpServletRequest。根据需要查抄 HttpServletRequest,也可修改 HttpServletRequest 头和数据。 在HttpServletResponse 到达客户端之前,拦截 HttpServletResponse。 根据需要查抄HttpServletResponse,也可修改 HttpServletResponse头和数据
  2.2 实现


/*和/**
在Spring MVC框架中,配置拦截器(Interceptor)的路径模式时,/*和/**这两个通配符有以下区别:

MyFilter01

  1. package com.dev.filter;
  2. import javax.servlet.*;
  3. import javax.servlet.annotation.WebFilter;
  4. import java.io.IOException;
  5. /**
  6. * 实现过滤器
  7. * 1. 实现javax.servlet.Filter接口
  8. * 2. 重写方法
  9. * 3. 在doFilter方法中编写过滤逻辑(控制资源访问)
  10. * 4,配置过滤器,设置拦截路径
  11. */
  12. // 拦截所有资源
  13. @WebFilter("/myServlet01")
  14. public class MyFilter01 implements Filter {
  15.  
  16.  
  17. @Override
  18.  
  19.  
  20. public void init(FilterConfig filterConfig) throws ServletException {
  21.  
  22.   }
  23.  
  24.  
  25. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  26.  
  27.  
  28.  
  29.  
  30. // 处理请求数据
  31.  
  32.  
  33.  
  34.  
  35. System.out.println("filter01start ");
  36.  
  37.  
  38.  
  39.  
  40. filterChain.doFilter(servletRequest, servletResponse);
  41.  
  42.  
  43.  
  44.  
  45. // 处理响应数据
  46.  
  47.  
  48.  
  49.  
  50. System.out.println("filter01end");
  51.  
  52.   }
  53.  
  54.  
  55. @Override
  56.  
  57.  
  58. public void destroy() {
  59.  
  60.   }
  61. }
复制代码
复制代码
MyFilter02

  1. package com.dev.filter;
  2. import javax.servlet.*;
  3. import javax.servlet.annotation.WebFilter;
  4. import java.io.IOException;
  5. /**
  6. * 实现过滤器
  7. * 1. 实现javax.servlet.Filter接口
  8. * 2. 重写方法
  9. * 3. 在doFilter方法中编写过滤逻辑(控制资源访问)
  10. * 4,配置过滤器,设置拦截路径
  11. */
  12. // 拦截所有资源
  13. @WebFilter("/myServlet02")
  14. public class MyFilter01 implements Filter {
  15.  
  16.  
  17. @Override
  18.  
  19.  
  20. public void init(FilterConfig filterConfig) throws ServletException {
  21.  
  22.   }
  23.  
  24.  
  25. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  26.  
  27.  
  28.  
  29.  
  30. // 处理请求数据
  31.  
  32.  
  33.  
  34.  
  35. System.out.println("filter02start ");
  36.  
  37.  
  38.  
  39.  
  40. filterChain.doFilter(servletRequest, servletResponse);
  41.  
  42.  
  43.  
  44.  
  45. // 处理响应数据
  46.  
  47.  
  48.  
  49.  
  50. System.out.println("filter02end");
  51.  
  52.   }
  53.  
  54.  
  55. @Override
  56.  
  57.  
  58. public void destroy() {
  59.  
  60.   }
  61. }
复制代码
MyServlet01

  1. package com.dev.filter;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.ServletRequest;
  4. import javax.servlet.ServletResponse;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import java.io.IOException;
  8. @WebServlet("/myServlet01")
  9. public class MyServlet01 extends HttpServlet {
  10.  
  11.  
  12. @Override
  13.  
  14.  
  15. public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  16.  
  17.  
  18.  
  19.  
  20. System.out.println("servlet01......");
  21.  
  22.   }
  23. }
复制代码
MyServlet02

  1. package com.dev.filter;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.ServletRequest;
  4. import javax.servlet.ServletResponse;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import java.io.IOException;
  8. @WebServlet("/myServlet02")
  9. public class MyServlet02 extends HttpServlet {
  10.  
  11.  
  12. @Override
  13.  
  14.  
  15. public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  16.  
  17.  
  18.  
  19.  
  20. System.out.println("servlet02......");
  21.  
  22.   }
  23. }
复制代码
复制代码

   注意
  
  访问
  
  2.3 说明


2.4 实行顺序

1. 利用 web.xml

过滤器的实行顺序就是它们在web.xml中声明的顺序。最先声明的过滤器将最先实行,而末了声明的过滤器将在响应阶段末了实行
  
  1. <!-- web.xml -->
  2. <filter>
  3.  
  4.  
  5. <filter-name>AuthFilter</filter-name>
  6.  
  7.  
  8. <filter-class>com.example.AuthFilter</filter-class>
  9. </filter>
  10. <filter-mapping>
  11.  
  12.  
  13. <filter-name>AuthFilter</filter-name>
  14.  
  15.  
  16. <url-pattern>/secure/*</url-pattern>
  17. </filter-mapping>
  18. <filter>
  19.  
  20.  
  21. <filter-name>LoggingFilter</filter-name>
  22.  
  23.  
  24. <filter-class>com.example.LoggingFilter</filter-class>
  25. </filter>
  26. <filter-mapping>
  27.  
  28.  
  29. <filter-name>LoggingFilter</filter-name>
  30.  
  31.  
  32. <url-pattern>/*</url-pattern>
  33. </filter-mapping>
复制代码
实行顺序说明

因此,纵然过滤器处理差异的URL模式,它们的实行顺序仍然基于配置文件中的声明顺序。

2. 利用注解和@Order

在Spring框架中,可以利用@WebFilter注解团结@Order注解来指定过滤器的实行顺序。@Order注解需要一个整数参数,数值越小的过滤器将越早实行
  1. @Order(1)
  2. @WebFilter(urlPatterns = "/*")
  3. public class FirstFilter implements Filter {
  4.  
  5.  
  6. // ...
  7. }
  8. @Order(2)
  9. @WebFilter(urlPatterns = "/*")
  10. public class SecondFilter implements Filter {
  11.  
  12.  
  13. // ...
  14. }
复制代码

3. 利用FilterRegistrationBean

在Spring Boot或Spring MVC中,你也可以通过FilterRegistrationBean在配置类中注册过滤器
  1. @Configuration
  2. public class FilterConfig {
  3.  
  4.  
  5. @Bean
  6.  
  7.  
  8. public FilterRegistrationBean<FirstFilter> firstFilterRegistration() {
  9.  
  10.  
  11.  
  12.  
  13. FilterRegistrationBean<FirstFilter> registration = new FilterRegistrationBean<>();
  14.  
  15.  
  16.  
  17.  
  18. registration.setFilter(new FirstFilter());
  19.  
  20.  
  21.  
  22.  
  23. registration.addUrlPatterns("/*");
  24.  
  25.  
  26.  
  27.  
  28. registration.setOrder(1);
  29.  
  30.  
  31.  
  32.  
  33. return registration;
  34.  
  35.   }
  36.  
  37.  
  38. @Bean
  39.  
  40.  
  41. public FilterRegistrationBean<SecondFilter> secondFilterRegistration() {
  42.  
  43.  
  44.  
  45.  
  46. FilterRegistrationBean<SecondFilter> registration = new FilterRegistrationBean<>();
  47.  
  48.  
  49.  
  50.  
  51. registration.setFilter(new SecondFilter());
  52.  
  53.  
  54.  
  55.  
  56. registration.addUrlPatterns("/*");
  57.  
  58.  
  59.  
  60.  
  61. registration.setOrder(2);
  62.  
  63.  
  64.  
  65.  
  66. return registration;
  67.  
  68.   }
  69. }
复制代码
复制代码

2.5字符乱码

哀求Tomcat7及以下版本Tomcat8及以上版本POST乱码,需要处理乱码,需要处理GET乱码,需要处理不会乱码,无需处理 处理

  1. package com.dev.filter;
  2. import javax.servlet.*;
  3. import javax.servlet.annotation.WebFilter;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. /**
  8. * 请求乱码统一处理
  9. *  tomcat8及以上版本 POST请求乱码问题
  10. *  tomecat7以下版本 POST/GET请求乱码问题
  11. */
  12. @WebFilter("/**")
  13. public class AEncodingFilter implements Filter {
  14.  
  15.  
  16.  
  17.  
  18. public AEncodingFilter(){
  19.  
  20.  
  21.  
  22.   }
  23.  
  24.  
  25. @Override
  26.  
  27.  
  28. public void init(FilterConfig filterConfig) throws ServletException {
  29.  
  30.  
  31.  
  32.   }
  33.  
  34.  
  35.  
  36.  
  37. @Override
  38.  
  39.  
  40. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  41.  
  42.  
  43.  
  44.  
  45. // 基于HTTP
  46.  
  47.  
  48.  
  49.  
  50. HttpServletRequest request = (HttpServletRequest) servletRequest;
  51.  
  52.  
  53.  
  54.  
  55. HttpServletResponse response = (HttpServletResponse) servletResponse;
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64. // 处理请求乱码问题
  65.  
  66.  
  67.  
  68.  
  69. request.setCharacterEncoding("UTF-8");
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78. // 放行
  79.  
  80.  
  81.  
  82.  
  83. filterChain.doFilter(request, response);
  84.  
  85.  
  86.  
  87.  
  88.  
  89.   }
  90.  
  91.  
  92.  
  93.  
  94. @Override
  95.  
  96.  
  97. public void destroy() {
  98.  
  99.  
  100.  
  101.   }
  102. }
复制代码
复制代码
三、监听器

3.1介绍

web 监听器是Servlet 中一种的特别的类,能资助开发者监听 web 中的特定事件,好比 ServletcontextHttpSession,ServletRequest 的创建和烧毁;变量的创建、烧毁和修改等。 可以在某些动作前后增加处理,实现监控。例如可以用来统计在线人数等。
3.2实现

监听器有三类8种:

3.3在线人数统计


OnlineListener

  1. package com.dev.listener;
  2. import javax.servlet.annotation.WebListener;
  3. import javax.servlet.http.HttpSessionEvent;
  4. import javax.servlet.http.HttpSessionListener;
  5. /**
  6. * 在线人数统计
  7. */
  8. @WebListener
  9. public class OnlineListener implements HttpSessionListener {
  10.  
  11.  
  12.  
  13.  
  14. // 得到在线人数
  15.  
  16.  
  17. public static int onlineCount = 0;
  18.  
  19.  
  20.  
  21.  
  22. /**
  23.  
  24.  
  25. * 当有新的session创建时,在线人数加一
  26.  
  27.  
  28. * @param httpSessionEvent
  29.  
  30.  
  31. */
  32.  
  33.  
  34. @Override
  35.  
  36.  
  37. public void sessionCreated(HttpSessionEvent httpSessionEvent) {
  38.  
  39.  
  40.  
  41.  
  42. onlineCount++;
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51. // 将在线人数放入session作用域中
  52.  
  53.  
  54.  
  55.  
  56. // httpSessionEvent.getSession().setAttribute("onlineCount", onlineCount);
  57.  
  58.  
  59.  
  60.  
  61. // 将在线任务放入application作用域中
  62.  
  63.  
  64.  
  65.  
  66. httpSessionEvent.getSession().getServletContext().setAttribute("onlineCount", onlineCount);
  67.  
  68.   }
  69.  
  70.  
  71.  
  72.  
  73. /**
  74.  
  75.  
  76. * 当session销毁时,在线人数减一
  77.  
  78.  
  79. * @param httpSessionEvent
  80.  
  81.  
  82. */
  83.  
  84.  
  85. @Override
  86.  
  87.  
  88. public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
  89.  
  90.  
  91.  
  92.  
  93. onlineCount--;
  94.  
  95.  
  96.  
  97.  
  98. // 将在线人数放入session作用域中
  99.  
  100.  
  101.  
  102.  
  103. // httpSessionEvent.getSession().setAttribute("onlineCount", onlineCount);
  104.  
  105.  
  106.  
  107.  
  108. // 将在线任务放入application作用域中
  109.  
  110.  
  111.  
  112.  
  113. httpSessionEvent.getSession().getServletContext().setAttribute("onlineCount", onlineCount);
  114.  
  115.   }
  116. }
复制代码
OnlineServlet2

  1. package com.dev.listener;
  2. import javax.servlet.annotation.WebServlet;
  3. import javax.servlet.http.HttpServlet;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. /**
  8. * 在线任务统计
  9. */
  10. @WebServlet("/online")
  11. public class OnlineServlet2 extends HttpServlet {
  12.  
  13.  
  14.  
  15.  
  16. @Override
  17.  
  18.  
  19. public void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28. //得到动作
  29.  
  30.  
  31.  
  32.  
  33. String action = req.getParameter("action");
  34.  
  35.  
  36.  
  37.  
  38. if ("logout".equals(action)) {
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45. // 退出
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52. req.getSession().invalidate();
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59. return;
  60.  
  61.  
  62.  
  63.   }
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72. // 得到当前访问的ip
  73.  
  74.  
  75.  
  76.  
  77. String ip = req.getRemoteAddr();
  78.  
  79.  
  80.  
  81.  
  82. System.out.println("当前访问的ip为:" + ip );
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95. // 获取session作用域中的在线人数
  96.  
  97.  
  98.  
  99.  
  100. // Integer onlineCount =(Integer) req.getSession().getAttribute("onlineCount");
  101.  
  102.  
  103.  
  104.  
  105. // 获取application作用域中的在线人数
  106.  
  107.  
  108.  
  109.  
  110. Integer onlineCount =(Integer) req.getSession().getServletContext().getAttribute("onlineCount");
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119. // 响应数据 在页面中显示人数
  120.  
  121.  
  122.  
  123.  
  124. res.setContentType("text/html;charset=utf-8");
  125.  
  126.  
  127.  
  128.  
  129. res.getWriter().write("当前在线人数为:" + onlineCount+"<a href='myServlet03?action=logout'>退出</a>");
  130.  
  131.  
  132.  
  133.  
  134. res.getWriter().flush();
  135.  
  136.  
  137.  
  138.  
  139. res.getWriter().close();
  140.  
  141.   }
  142. }
复制代码
复制代码
四、拦截器

4.1介绍

拦截器(Interceptor)是Java Web应用中的一种设计模式,主要用于在哀求到达目的组件(如控制器)之前或响应离开目的组件之后实行一些特定的逻辑。在Spring框架中,拦截器是AOP(面向切面编程)的一个应用,可以用来实现诸如权限验证、日志记录、事务管理、性能监控等功能。
4.2实现方式

1.实现HandlerInterceptor接口

在Spring MVC中,拦截器可以通过实现HandlerInterceptor接口来创建
该接口包罗三个方法:

  1.  
复制代码
  1. import org.springframework.web.servlet.HandlerInterceptor;
  2.  
  3. import org.springframework.web.servlet.ModelAndView;
  4.  
  5. import javax.servlet.http.HttpServletRequest;
  6.  
  7. import javax.servlet.http.HttpServletResponse;
  8.  
  9. public class CustomInterceptor implements HandlerInterceptor {
  10.  
  11.  
  12.  
  13. @Override
  14.  
  15.  
  16.  
  17. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  18.  
  19.  
  20.  
  21.  
  22.  
  23. // 在这里实现你的逻辑
  24.  
  25.  
  26.  
  27.  
  28.  
  29. return true;
  30.  
  31.  
  32.  
  33. }
  34.  
  35.  
  36.  
  37. @Override
  38.  
  39.  
  40.  
  41. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  42.  
  43.  
  44.  
  45.  
  46.  
  47. // 在这里实现你的逻辑
  48.  
  49.  
  50.  
  51. }
  52.  
  53.  
  54.  
  55. @Override
  56.  
  57.  
  58.  
  59. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  60.  
  61.  
  62.  
  63.  
  64.  
  65. // 在这里实现你的逻辑
  66.  
  67.  
  68.  
  69. }
  70.  
  71. }
  72.  
复制代码
2.实现WebRequestInterceptor接口

这个接口与HandlerInterceptor雷同,但是它在更早的阶段被调用,以致在哀求映射之前。这使得它适合做一些全局的初始化工作。实现WebRequestInterceptor接口需要重写以下方法:


3.继续HandlerInterceptorAdapter类

如果你不想实现HandlerInterceptor接口中的全部方法,可以继续HandlerInterceptorAdapter类,这是一个适配器类,它为HandlerInterceptor接口提供了默认实现,你只需要重写你感兴趣的方法即可。
  1.  
复制代码
  1. import org.springframework.web.servlet.HandlerInterceptorAdapter;​  
  2. public class CustomInterceptor extends HandlerInterceptorAdapter {​  
  3.  
  4.  
  5. @Override  
  6.  
  7.  
  8. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  9.  
  10.  
  11.  
  12.  
  13. // 在这里实现你的逻辑  
  14.  
  15.  
  16.  
  17.  
  18. return true;  
  19.  
  20.  
  21. }  
  22. }
复制代码
  1.  
复制代码
4.注册拦截器

一旦你创建了拦截器,就需要在Spring配置中注册它。这可以通过实现WebMvcConfigurer接口的addInterceptors方法来完成。
  1. import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;​@Configurationpublic class WebConfig implements WebMvcConfigurer {​  
  2.  
  3. @Override  
  4.  
  5. public void addInterceptors(InterceptorRegistry registry) {  
  6.  
  7.  
  8.  
  9. registry.addInterceptor(new CustomInterceptor())  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.   .addPathPatterns("/**"); // 指定拦截器应用的全部哀求  
  17.   }}​
复制代码

4.3解决的标题

拦截器可以解决多种标题:

4.4与Spring Boot的集成

在Spring Boot中利用拦截器,可以通过以下步调:

  1. import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;​import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;​public class MyInterceptor implements HandlerInterceptor {​  
  2.  
  3. @Override  
  4.  
  5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  6.  
  7.  
  8.  
  9. System.out.println("Pre-handle logic...");  
  10.  
  11.  
  12.  
  13. return true; // 返回true表示继续处理哀求  
  14.   }​  
  15.  
  16. @Override  
  17.  
  18. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {  
  19.  
  20.  
  21.  
  22. System.out.println("Post-handle logic...");  
  23.   }​  
  24.  
  25. @Override  
  26.  
  27. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {java  
  28.  
  29.  
  30.  
  31. System.out.println("After completion logic...");  
  32.   }}​
复制代码
接下来,在Spring配置类中注册这个拦截器
  1. import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;​@Configurationpublic class WebConfig implements WebMvcConfigurer {​  
  2.  
  3. @Override  
  4.  
  5. public void addInterceptors(InterceptorRegistry registry) {  
  6.  
  7.  
  8.  
  9. registry.addInterceptor(new MyInterceptor())  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.   .addPathPatterns("/**"); // 指定拦截器应用的全部哀求  
  17.   }}​
复制代码

4.4实行顺序控制

拦截器的实行顺序可以通过以下方式控制:

  1. import org.springframework.core.Ordered;import org.springframework.web.servlet.HandlerInterceptor;​public class MyInterceptor implements HandlerInterceptor, Ordered {​  
  2.  
  3. @Override  
  4.  
  5. public int getOrder() {  
  6.  
  7.  
  8.  
  9. return 1; // 优先级高于其他返回值大于1的拦截器  
  10.   }​  
  11.  
  12. // 其他方法...}
复制代码
复制代码
4.5身份验证明例

假设我们有一个Spring Boot应用,此中某些资源是受掩护的,只有颠末身份验证的用户才能访问。我们可以利用拦截器来查抄用户的会话状态,确保只有已登录的用户才能访问这些资源。
步调一:创建拦截器

起首,我们需要创建一个拦截器类,实现HandlerInterceptor接口,并覆盖preHandle方法来实行身份验证逻辑。
  1. import org.springframework.stereotype.Component;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;​import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;​@Componentpublic class AuthenticationInterceptor implements HandlerInterceptor {​  
  2.  
  3. @Override  
  4.  
  5. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
  6.  
  7.  
  8.  
  9. // 从session中获取用户信息  
  10.  
  11.  
  12.  
  13. HttpSession session = request.getSession(false);  
  14.  
  15.  
  16.  
  17. if (session != null) {  
  18.  
  19.  
  20.  
  21.  
  22.  
  23. Object user = session.getAttribute("user");  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. if (user != null) {  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37. // 用户已登录,答应哀求继续  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45. return true;  
  46.  
  47.  
  48.  
  49.  
  50.   }  
  51.  
  52.  
  53.   }  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. // 用户未登录,重定向到登录页面  
  62.  
  63.  
  64.  
  65. response.sendRedirect(request.getContextPath() + "/login");  
  66.  
  67.  
  68.  
  69. return false;  
  70.   }​  
  71.  
  72. @Override  
  73.  
  74. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {  
  75.  
  76.  
  77.  
  78. // 这里可以处理哀求后的逻辑,例如日志记录  
  79.   }​  
  80.  
  81. @Override  
  82.  
  83. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {  
  84.  
  85.  
  86.  
  87. // 这里可以处理哀求完成后的清理工作  
  88.   }}
复制代码

步调二:配置拦截器

接下来,我们需要在Spring配置类中注册这个拦截器,并指定它应该应用于哪些URL。
  1. import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;​@Configurationpublic class WebConfig implements WebMvcConfigurer {​  
  2.  
  3. @Override  
  4.  
  5. public void addInterceptors(InterceptorRegistry registry) {  
  6.  
  7.  
  8.  
  9. registry.addInterceptor(new AuthenticationInterceptor())  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.   .addPathPatterns("/protected/*") // 指定拦截器应用于/protected下的全部哀求  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.   .excludePathPatterns("/protected/login", "/protected/logout"); // 排除登录和登出路经  
  24.   }}​
复制代码
步调三:测试

如今,每当有哀求尝试访问/protected/*下的资源时,AuthenticationInterceptor都会被调用。如果用户没有登录,他们将被重定向到登录页面。如果已经登录,则哀求将继续正常处理。
注意事项


通过这种方式,拦截器可以资助我们在Spring Boot应用中实现细粒度的访问控制,进步应用的安全性和健壮性。

五、过滤器和拦截器区别 (面试常问)

过滤器(Filter)和拦截器(Interceptor)在Java Web应用步调中饰演偏紧张的脚色,它们用于在哀求到达目的组件(如Servlet或JSP)之前或之后实行特定的逻辑。两者都可以在哀求过程中参与并可能阻止哀求。
尽管它们有相似的功能,但它们在实现机制、作用范围、依赖环境等方面存在明显差异。


六、如何理解"拦截器只能拦截部分web哀求"

截器主要用于拦截和处理由控制器(Controller)处理的哀求,而不是全部的Web哀求。
这是由于拦截器的设计初衷是为了处理业务逻辑层面的哀求,如权限查抄、日志记录、数据预处理等,这些通常与具体的业务操作相关联。
1.拦截器的作用范围


2.为什么拦截器不能拦截全部Web哀求?


3.如何拦截全部Web哀求?


总结来说,拦截器在Spring MVC中主要用于处理与业务逻辑相关的哀求,而过滤器则可以用于处理全部类型的Web哀求,包括静态资源哀求。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4