☆ 什么是过滤器
过滤器(Filter)是在Web应用程序中用来拦截和处理哀求/响应的组件。它们按照肯定的次序链式地处理每个传入的HTTP哀求,并可以在哀求被处理前或响应被发送回客户端后执行某些逻辑。
常用于做权限查抄认证,记载日志操纵、拦截过滤哀求、敏感数据处理,同一编码处理等。
☆ 过滤器的生命周期
- 初始化
此方法只运行一次,当Web应用程序启动时,Servlet容器会为每个界说的过滤器创建一个实例,并调用其init()方法。通常用来读取配置文件和初始化资源,执行一些必要的初始化操纵。
- init(FilterConfig filterConfig):
参数:filterConfig 提供了访问过滤器配置信息的方式,比如初始化参数。
注意事项:在这个阶段,不应该进行耗时的操纵,由于这会影响应用的启动速度。
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- // 执行初始化逻辑,如读取配置参数等
- }
复制代码
- 哀求处理
一旦过滤器被初始化,它就会进入活动状态,每当有新的哀求到来时,容器会调用过滤器的doFilter()方法。这是过滤器的焦点部门,可以在其中添加自界说过滤逻辑来查抄、修改哀求或响应。
- doFilter(ServletRequest request, ServletResponse response, FilterChain chain):
参数:
request:当前的HTTP哀求对象。
response:即将发送给客户端的HTTP响应对象。
chain:表现过滤器链的对象,用于将哀求传递给下一个过滤器或最终的目标资源。
注意事项:在这个方法内部,你可以选择是否继承调用chain.doFilter()来让哀求继承沿过滤器链进步,或者直接结束哀求并返反响应。
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- // 在这里添加过滤逻辑
- try {
- // 可选:预处理请求
-
- // 继续调用下一个过滤器或目标资源
- chain.doFilter(request, response);
-
- // 可选:后处理响应
- } catch (Exception e) {
- // 异常处理逻辑
- }
- }
复制代码
- 烧毁
过滤器烧毁之前会调用destroy()方法,通知过滤器释放其所占用的全部资源。此方法只运行一次,通常用作关闭数据库连接、注销监听器等。
- destroy():
没有参数。
注意事项:应该确保全部已分配的资源都被正确释放,以克制内存走漏或其他问题。
- @Override
- public void destroy() {
- // 执行清理逻辑,如关闭资源等
- }
复制代码 ☆ 使用场景
- 身份验证与授权:确保只有经过认证和授权的用户才气访问某些特定的资源
- 日志记载:记载全部哀求信息,包罗但不限于访问时间、来源IP地址、哀求方法、URI等,有助于体系管理和安全监控。
- 同一编码格式:确保全部传入和传出的数据都使用同一的字符编码格式,克制不同字符集兼容、乱码问题。
- XSS防护:防止跨站脚本攻击,确保输入输出的安全性。
- CSRF防护:防止跨站哀求伪造攻击,确保表单提交的真实性和完整性。
- 性能监控:收集有关哀求处理时间和吞吐量的数据,资助优化体系性能。
……
☆ 如何使用
在Springboot中,实现过滤器的方式有多种,如何使用取决于本身的习惯偏好,以下是几种常见实现方式:
- 直接实现Filter接口
最根本的实现方式,自界说类实现Filter接口。
- import javax.servlet.*;
- import java.io.IOException;
- @Slf4j
- @Component
- @Order(1)
- public class MyCustomFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- // 初始化逻辑
- log.info("filter1 init……");
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- log.info("=================:{}", "在这里添加过滤逻辑");
- // 继续调用下一个过滤器或目标资源
- chain.doFilter(request, response);
- }
- @Override
- public void destroy() {
- // 清理逻辑
- log.info("filter1 destroy……");
- }
- }
复制代码 注册过滤器:
可以通过配置类手动注册这个过滤器,或者使用@Component注解让Spring主动检测到它,过滤器的次序可以通过注解@Order指定。
- 扩展OncePerRequestFilter
如果渴望确保过滤器只针对每个哀求执行一次(即使存在多层转发或其他内部哀求),通过扩展OncePerRequestFilter类,可以克制重复执行过滤逻辑。
- import org.springframework.web.filter.OncePerRequestFilter;
- import javax.servlet.FilterChain;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- public class CustomOncePerRequestFilter extends OncePerRequestFilter {
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
- // 自定义逻辑
- super.doFilterInternal(request, response, filterChain);
- }
- }
复制代码
- 同样可以通过配置类或@Component注解来注册。
基于注解@WebFilter 和 @ServletComponentScan
起首必要在主应用程序类或启动类上添加启用@ServletComponentScan注解,用以扫描并注册带有@WebFilter注解的组件。
示例代码:编写过滤器实现Filter
- import javax.servlet.annotation.WebFilter;
- import javax.servlet.annotation.WebInitParam;
- 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 java.io.IOException;
- @WebFilter(urlPatterns = "user/*", filterName = "filter1", initParams = @WebInitParam(name = "paramName", value = "paramValue"))
- @Slf4j
- public class UserFilter implements Filter {
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- // 初始化逻辑
- log.info("filter1 init……");
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- // 过滤逻辑
- HttpServletRequest request1 = (HttpServletRequest) servletRequest;
- String token = request1.getHeader("token");
- log.info("token值:{}", token);
- if (token != null) {
- //该方法执行后直接运行至下一个过滤器
- chain.doFilter(request, response);
- } else {
- log.info("错误处理:{}", "非法用户");
- }
- }
- @Override
- public void destroy() {
- // 清理逻辑
- log.info("filter1 destroy……");
- }
- }
复制代码 启用扫描:
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.boot.web.servlet.ServletComponentScan;
- @SpringBootApplication
- @ServletComponentScan //过滤器扫描
- public class MyApplication {
- public static void main(String[] args) {
- SpringApplication.run(MyApplication.class, args);
- }
- }
复制代码
- 通过配置类注册过滤器
通过编写配置类并在其中界说@Bean来注册过滤器。这种方法提供了更大的灵活性,可以在这里指定URL模式、初始化参数以及过滤器的次序等。
- import org.springframework.boot.web.servlet.FilterRegistrationBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- @Configuration
- public class FilterConfig {
- @Bean
- public FilterRegistrationBean<MyCustomFilter> loggingFilter(){
- FilterRegistrationBean<MyCustomFilter> registrationBean = new FilterRegistrationBean<>();
- registrationBean.setFilter(new MyCustomFilter());
- registrationBean.addUrlPatterns("/api/*"); // 指定过滤器适用的URL模式
- registrationBean.setOrder(1); // 设置过滤器的优先级
- return registrationBean;
- }
- }
复制代码 ☆ 参考:文章 FC464782123
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |