Java之过滤器Filter

介绍

过滤器是一种对象,它对资源的请求(servlet或静态内容)或来自资源的响应执行过滤任务或者两者都执行,在一个web应用中,可以开发编写多个Filter,这些Filter组合起来组合成一个Filter链若是一个过滤器链,先配置先执行,执行顺序是根据类名的的排序(请求时的执行顺序),响应时以相反的顺序执行
过滤器在doFilter方法中执行过滤。 每个Filter都可以访问一个FilterConfig对象,它可以从中获取它的初始化参数,以及一个对ServletContext的引用,例如,它可以使用这个引用来加载过滤任务所需的资源。
过滤器在web应用程序的部署描述符中配置。
为该设计确定的例子有:

  1. 身份验证过滤器
  2. 日志记录和审计过滤器
  3. 图像转换过滤器
  4. 数据压缩过滤器
  5. 加密的过滤器
  6. 分过滤器
  7. 触发资源访问事件的过滤器
  8. XSL / T过滤器
  9. mime类型过滤器链

实现

需要用到的依赖

<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>tomcat-servlet-api</artifactId>
  <version>9.0.58</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>4.0.1</version>
  <scope>provided</scope>
</dependency>

Filter类

package filter;


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/s01")
public class Filter01 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter01的init方法");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter01的doFilter方法");
        // 放行资源
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("Filter01的响应之后方法");
    }

    @Override
    public void destroy() {
        System.out.println("Filter01的destroy方法");
    }
}

Servlet类

package servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/s01")
public class Servlet01 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet01的service方法");
    }
}

访问后http://localhost:8080/filter/s01打印

Filter01的doFilter方法
Servlet01的service方法
Filter01的响应之后方法

结论:

  1. 先执行过滤器的方法再执行servlet的方法
  2. 响应后会执行过滤器的filterChain.doFilter(servletRequest, servletResponse);后面的代码
  3. 过滤器也可以设置拦截路径,只对特殊的路径进行拦截

利用过滤器解决的实际问题

请求乱码处理

乱码情况

  1. post请求,所有版本的Tomcat都需要处理,处理方式为servletRequest.setCharacterEncoding("UTF-8");
  2. GET请求Tomcat8及以上版本不会乱码,Tomcat7及以下版本会乱码,需要处理

代码案例

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@WebFilter("/")
public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 基于Http的
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 处理get请求且服务器版本在Tomcat8以下
        String method = request.getMethod();
        if ("GET".equalsIgnoreCase(method)) {
            // 获取服务器版本
            String webVersion = request.getServletContext().getServerInfo();
            String version = webVersion.substring(webVersion.indexOf("/") + 1, webVersion.indexOf("."));
            if (Integer.parseInt(version) < 8) {
                // 得到自定义的内部类,(MyWapper继承了)
                HttpServletRequest myRequest = new Mywapper(request);
                filterChain.doFilter(myRequest, servletResponse);
                return;
            }
            filterChain.doFilter(servletRequest, servletResponse);
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }

    class Mywapper extends HttpServletRequestWrapper {

        // 定义成员变量,提升构造器中的request对象的范围
        private HttpServletRequest request;

        public Mywapper(HttpServletRequest request) {
            super(request);
            this.request = request;
        }

        @Override
        public String getParameter(String name) {
            String value = request.getParameter(name);
            if (value != value && !"".equals(value.trim())) {
                value = new String(value.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            }
            return value;
        }
    }
}

非法请求拦截

就是有些需要验证通过或者任何情况下都不允许用户访问,直接设置拦截器的拦截路径即可,进入此拦截器就返回

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值