Springboot焦点:过滤器

海哥  金牌会员 | 2025-2-17 01:22:17 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 880|帖子 880|积分 2640

☆ 什么是过滤器

   过滤器(Filter)是在Web应用程序中用来拦截和处理哀求/响应的组件。它们按照肯定的次序链式地处理每个传入的HTTP哀求,并可以在哀求被处理前或响应被发送回客户端后执行某些逻辑。
常用于做权限查抄认证,记载日志操纵、拦截过滤哀求、敏感数据处理,同一编码处理等。
  ☆ 过滤器的生命周期



  • 初始化
    此方法只运行一次,当Web应用程序启动时,Servlet容器会为每个界说的过滤器创建一个实例,并调用其init()方法。通常用来读取配置文件和初始化资源,执行一些必要的初始化操纵。

    • init(FilterConfig filterConfig):
      参数:filterConfig 提供了访问过滤器配置信息的方式,比如初始化参数。
      注意事项:在这个阶段,不应该进行耗时的操纵,由于这会影响应用的启动速度。

  1. @Override
  2. public void init(FilterConfig filterConfig) throws ServletException {
  3.     // 执行初始化逻辑,如读取配置参数等
  4. }
复制代码


  • 哀求处理
    一旦过滤器被初始化,它就会进入活动状态,每当有新的哀求到来时,容器会调用过滤器的doFilter()方法。这是过滤器的焦点部门,可以在其中添加自界说过滤逻辑来查抄、修改哀求或响应。

    • doFilter(ServletRequest request, ServletResponse response, FilterChain chain):
      参数:
      request:当前的HTTP哀求对象。
      response:即将发送给客户端的HTTP响应对象。
      chain:表现过滤器链的对象,用于将哀求传递给下一个过滤器或最终的目标资源。
      注意事项:在这个方法内部,你可以选择是否继承调用chain.doFilter()来让哀求继承沿过滤器链进步,或者直接结束哀求并返反响应。

  1. @Override
  2. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  3.         throws IOException, ServletException {
  4.     // 在这里添加过滤逻辑
  5.     try {
  6.         // 可选:预处理请求
  7.         
  8.         // 继续调用下一个过滤器或目标资源
  9.         chain.doFilter(request, response);
  10.         
  11.         // 可选:后处理响应
  12.     } catch (Exception e) {
  13.         // 异常处理逻辑
  14.     }
  15. }
复制代码


  • 烧毁
    过滤器烧毁之前会调用destroy()方法,通知过滤器释放其所占用的全部资源。此方法只运行一次,通常用作关闭数据库连接、注销监听器等。

    • destroy():
      没有参数。
      注意事项:应该确保全部已分配的资源都被正确释放,以克制内存走漏或其他问题。

  1. @Override
  2. public void destroy() {
  3.     // 执行清理逻辑,如关闭资源等
  4. }
复制代码
☆ 使用场景


  • 身份验证与授权:确保只有经过认证和授权的用户才气访问某些特定的资源
  • 日志记载:记载全部哀求信息,包罗但不限于访问时间、来源IP地址、哀求方法、URI等,有助于体系管理和安全监控。
  • 同一编码格式:确保全部传入和传出的数据都使用同一的字符编码格式,克制不同字符集兼容、乱码问题。
  • XSS防护:防止跨站脚本攻击,确保输入输出的安全性。
  • CSRF防护:防止跨站哀求伪造攻击,确保表单提交的真实性和完整性。
  • 性能监控:收集有关哀求处理时间和吞吐量的数据,资助优化体系性能。
    ……
☆ 如何使用
在Springboot中,实现过滤器的方式有多种,如何使用取决于本身的习惯偏好,以下是几种常见实现方式:


  • 直接实现Filter接口
    最根本的实现方式,自界说类实现Filter接口。
  1. import javax.servlet.*;
  2. import java.io.IOException;
  3. @Slf4j
  4. @Component
  5. @Order(1)
  6. public class MyCustomFilter implements Filter {
  7.     @Override
  8.     public void init(FilterConfig filterConfig) throws ServletException {
  9.          // 初始化逻辑
  10.         log.info("filter1 init……");
  11.     }
  12.     @Override
  13.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  14.             throws IOException, ServletException {
  15.         log.info("=================:{}", "在这里添加过滤逻辑");        
  16.         // 继续调用下一个过滤器或目标资源
  17.         chain.doFilter(request, response);
  18.     }
  19.     @Override
  20.     public void destroy() {
  21.         // 清理逻辑
  22.         log.info("filter1 destroy……");
  23.     }
  24. }
复制代码
注册过滤器
可以通过配置类手动注册这个过滤器,或者使用@Component注解让Spring主动检测到它,过滤器的次序可以通过注解@Order指定。


  • 扩展OncePerRequestFilter
    如果渴望确保过滤器只针对每个哀求执行一次(即使存在多层转发或其他内部哀求),通过扩展OncePerRequestFilter类,可以克制重复执行过滤逻辑。
  1. import org.springframework.web.filter.OncePerRequestFilter;
  2. import javax.servlet.FilterChain;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. public class CustomOncePerRequestFilter extends OncePerRequestFilter {
  8.     @Override
  9.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  10.             throws ServletException, IOException {
  11.         // 自定义逻辑
  12.         super.doFilterInternal(request, response, filterChain);
  13.     }
  14. }
复制代码


  • 同样可以通过配置类或@Component注解来注册。
基于注解@WebFilter 和 @ServletComponentScan
起首必要在主应用程序类或启动类上添加启用@ServletComponentScan注解,用以扫描并注册带有@WebFilter注解的组件。
示例代码:编写过滤器实现Filter
  1. import javax.servlet.annotation.WebFilter;
  2. import javax.servlet.annotation.WebInitParam;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. import java.io.IOException;
  10. @WebFilter(urlPatterns = "user/*", filterName = "filter1", initParams = @WebInitParam(name = "paramName", value = "paramValue"))
  11. @Slf4j
  12. public class UserFilter implements Filter {
  13.     @Override
  14.     public void init(FilterConfig filterConfig) throws ServletException {
  15.         // 初始化逻辑
  16.         log.info("filter1 init……");
  17.     }
  18.     @Override
  19.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  20.             throws IOException, ServletException {
  21.         // 过滤逻辑
  22.         HttpServletRequest request1 = (HttpServletRequest) servletRequest;
  23.         String token = request1.getHeader("token");
  24.         log.info("token值:{}", token);
  25.         if (token != null) {
  26.             //该方法执行后直接运行至下一个过滤器
  27.             chain.doFilter(request, response);
  28.         } else {
  29.             log.info("错误处理:{}", "非法用户");
  30.         }
  31.     }
  32.     @Override
  33.     public void destroy() {
  34.         // 清理逻辑
  35.         log.info("filter1 destroy……");
  36.     }
  37. }
复制代码
启用扫描:
  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.boot.web.servlet.ServletComponentScan;
  4. @SpringBootApplication
  5. @ServletComponentScan //过滤器扫描
  6. public class MyApplication {
  7.     public static void main(String[] args) {
  8.         SpringApplication.run(MyApplication.class, args);
  9.     }
  10. }
复制代码


  • 通过配置类注册过滤器
    通过编写配置类并在其中界说@Bean来注册过滤器。这种方法提供了更大的灵活性,可以在这里指定URL模式、初始化参数以及过滤器的次序等。
  1. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. @Configuration
  5. public class FilterConfig {
  6.     @Bean
  7.     public FilterRegistrationBean<MyCustomFilter> loggingFilter(){
  8.         FilterRegistrationBean<MyCustomFilter> registrationBean = new FilterRegistrationBean<>();
  9.         registrationBean.setFilter(new MyCustomFilter());
  10.         registrationBean.addUrlPatterns("/api/*"); // 指定过滤器适用的URL模式
  11.         registrationBean.setOrder(1); // 设置过滤器的优先级
  12.         return registrationBean;
  13.     }
  14. }
复制代码
☆ 参考:文章 FC464782123

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

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表