JavaWeb过滤器Filter怎么使用

发布时间:2022-09-26 14:18:07 作者:iii
来源:亿速云 阅读:185
# JavaWeb过滤器Filter怎么使用

## 一、Filter概述

### 1.1 什么是Filter
Filter(过滤器)是JavaWeb三大组件(Servlet、Filter、Listener)之一,它可以在请求到达目标资源之前或响应返回客户端之前对HTTP请求和响应进行拦截处理。

### 1.2 Filter的作用
- 权限控制:如登录验证、权限检查
- 日志记录:记录请求信息
- 编码处理:统一设置请求/响应编码
- 数据压缩:对响应内容进行压缩
- 敏感词过滤:替换请求/响应中的敏感词汇

### 1.3 Filter的生命周期
1. **初始化阶段**:Web应用启动时调用`init()`方法
2. **拦截阶段**:每次请求时调用`doFilter()`方法
3. **销毁阶段**:Web应用停止时调用`destroy()`方法

## 二、Filter开发步骤

### 2.1 实现Filter接口
创建一个Java类实现`javax.servlet.Filter`接口:

```java
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化代码
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                         FilterChain chain) throws IOException, ServletException {
        // 过滤处理代码
        chain.doFilter(request, response); // 放行请求
    }
    
    @Override
    public void destroy() {
        // 资源释放代码
    }
}

2.2 配置Filter

在web.xml中配置:

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
    <!-- 初始化参数 -->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <!-- 支持dispatcher类型 -->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

或使用注解方式(Servlet 3.0+):

@WebFilter(
    filterName = "myFilter",
    urlPatterns = "/*",
    initParams = {
        @WebInitParam(name = "encoding", value = "UTF-8")
    },
    dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}
)
public class MyFilter implements Filter {
    // 实现代码
}

三、Filter核心API详解

3.1 FilterConfig接口

3.2 FilterChain接口

3.3 请求/响应对象

Filter可以处理HttpServletRequestHttpServletResponse对象,常用方法包括: - setCharacterEncoding(String encoding):设置编码 - getHeader(String name):获取请求头 - setHeader(String name, String value):设置响应头

四、Filter典型应用场景

4.1 统一编码设置

public class EncodingFilter implements Filter {
    private String encoding;
    
    @Override
    public void init(FilterConfig config) {
        this.encoding = config.getInitParameter("encoding");
        if(this.encoding == null) {
            this.encoding = "UTF-8";
        }
    }
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, 
                         FilterChain chain) throws IOException, ServletException {
        req.setCharacterEncoding(encoding);
        resp.setCharacterEncoding(encoding);
        chain.doFilter(req, resp);
    }
}

4.2 登录验证

public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, 
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        
        String uri = request.getRequestURI();
        if(uri.contains("/login.jsp") || uri.contains("/loginServlet")) {
            chain.doFilter(request, response);
            return;
        }
        
        if(request.getSession().getAttribute("user") != null) {
            chain.doFilter(request, response);
        } else {
            response.sendRedirect(request.getContextPath() + "/login.jsp");
        }
    }
}

4.3 敏感词过滤

public class SensitiveFilter implements Filter {
    private List<String> sensitiveWords = new ArrayList<>();
    
    @Override
    public void init(FilterConfig config) {
        // 从配置文件加载敏感词
        sensitiveWords.add("敏感词1");
        sensitiveWords.add("敏感词2");
    }
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, 
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        
        // 包装请求对象
        SensitiveRequestWrapper wrapper = new SensitiveRequestWrapper(request, sensitiveWords);
        chain.doFilter(wrapper, response);
    }
}

// 自定义RequestWrapper
class SensitiveRequestWrapper extends HttpServletRequestWrapper {
    private List<String> sensitiveWords;
    
    public SensitiveRequestWrapper(HttpServletRequest request, List<String> sensitiveWords) {
        super(request);
        this.sensitiveWords = sensitiveWords;
    }
    
    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        if(value != null) {
            for(String word : sensitiveWords) {
                value = value.replaceAll(word, "***");
            }
        }
        return value;
    }
}

五、Filter高级特性

5.1 过滤器链

多个Filter可以组成过滤器链,执行顺序取决于web.xml中的配置顺序或注解的类名顺序。

5.2 动态注册Filter(Servlet 3.0+)

public class MyInitializer implements ServletContainerInitializer {
    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
        FilterRegistration.Dynamic filter = ctx.addFilter("dynamicFilter", DynamicFilter.class);
        filter.addMappingForUrlPatterns(
            EnumSet.of(DispatcherType.REQUEST), true, "/*");
        filter.setInitParameter("param1", "value1");
    }
}

5.3 异步支持(Servlet 3.0+)

@WebFilter(asyncSupported = true, urlPatterns = "/*")
public class AsyncFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, 
                         FilterChain chain) throws IOException, ServletException {
        AsyncContext asyncContext = req.startAsync();
        asyncContext.start(() -> {
            try {
                chain.doFilter(asyncContext.getRequest(), asyncContext.getResponse());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                asyncContext.complete();
            }
        });
    }
}

六、常见问题与解决方案

6.1 Filter执行顺序问题

6.2 Filter无法拦截静态资源

6.3 性能优化建议

  1. 避免在Filter中执行耗时操作
  2. 合理设计过滤器链,减少不必要的Filter
  3. 对于静态资源考虑使用<dispatcher>REQUEST</dispatcher>
  4. 合理使用缓存机制

七、总结

Filter作为JavaWeb开发中的重要组件,提供了强大的请求/响应拦截处理能力。通过本文的学习,你应该已经掌握了:

  1. Filter的基本概念和工作原理
  2. Filter的开发与配置方法
  3. Filter的典型应用场景实现
  4. Filter的高级特性和优化技巧

在实际项目中,合理使用Filter可以大幅提高代码的复用性和系统的可维护性。建议根据具体需求设计适当的过滤器链,并注意性能和安全方面的考量。

附录:完整示例代码

编码过滤器

@WebFilter(
    urlPatterns = "/*",
    initParams = @WebInitParam(name = "encoding", value = "UTF-8")
)
public class EncodingFilter implements Filter {
    private String encoding;
    
    @Override
    public void init(FilterConfig config) {
        this.encoding = config.getInitParameter("encoding");
    }
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, 
                         FilterChain chain) throws IOException, ServletException {
        req.setCharacterEncoding(encoding);
        resp.setCharacterEncoding(encoding);
        chain.doFilter(req, resp);
    }
}

登录检查过滤器

@WebFilter(
    urlPatterns = {"/user/*", "/admin/*"},
    dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}
)
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, 
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        
        HttpSession session = request.getSession(false);
        if(session == null || session.getAttribute("user") == null) {
            response.sendRedirect(request.getContextPath() + "/login.jsp?redirect=" + 
                URLEncoder.encode(request.getRequestURI(), "UTF-8"));
            return;
        }
        
        chain.doFilter(request, response);
    }
}

通过以上示例和说明,相信你已经掌握了JavaWeb Filter的使用方法。在实际开发中,可以根据项目需求灵活组合各种过滤器,构建强大的Web应用程序。 “`

推荐阅读:
  1. Java中Filter过滤器的使用
  2. Javaweb之Filter案例练习-项目全局编码过滤器

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

javaweb filter

上一篇:JavaWeb怎么部署到Linux服务器

下一篇:JavaWeb怎么实现登录验证码

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》