javaee-过滤器

2022/12/14 java

# 入门

1.创建一个java类实现Filter接口

public class MyFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器被初始化了");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("过滤器被执行了");
    }
    @Override
    public void destroy() {
        System.out.println("过滤器被销毁了");
    }
}

2.配置web.xml

  <!-- 配置过滤器 -->
  <filter>
      <filter-name>myFilter</filter-name>
      <filter-class>com.zh.filter.MyFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>myFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

3.测试servlet

public class TestServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("我是servlet");
    }
}

4.结果

浏览器:
http://localhost:8000/Filter/test
控制台:
过滤器被初始化了
过滤器被执行了

5.分析

访问test被过滤器拦截,执行过滤器doFilter里的方法,并没有放行所以没有执行test里的方法

# 过滤器的放行

//过滤器放行
chain.doFilter(request, response);

完整代码

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    System.out.println("过滤器被执行了1");
    //过滤器放行
    chain.doFilter(request, response);
    System.out.println("过滤器被执行了2");
}

运行结果

浏览器:
http://localhost:8000/Filter/test
控制台:
过滤器被初始化了
过滤器被执行了1
我是servlet
过滤器被执行了2

分析:

1.浏览器访问test被过滤器拦截

2.执行过滤器里的代码,

3.过滤器放行执行test里代码,

4.test响应浏览器时又被过滤器拦截,执行下面的代码。

# url-pattern配置

1.servlet配置

//servlet
public class TestServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("TestServlet.service(我是servlet)");
    }
}

2.配置web.xml

<!--servlet配置-->
<servlet>
  <description></description>
  <display-name>TestServlet</display-name>
  <servlet-name>TestServlet</servlet-name>
  <servlet-class>com.zh.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>TestServlet</servlet-name>
  <url-pattern>/test.do</url-pattern>
</servlet-mapping>

3.拦截器配置

第一个拦截器

//第一个拦截器 MyFilter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("MyFilter.doFilter(我被执行了)");
        chain.doFilter(request, response);
        System.out.println("MyFilter.doFilter(我被执行了2)");
}

第二个拦截器

//第二个拦截器 MyFilter2
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
    System.out.println("MyFilter2.doFilter(我是第二个拦截器)");
    chain.doFilter(request, response);   
}

第三个拦截器

//第三个拦截器 MyFilter3
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("MyFilter3.doFilter(我是第三个拦截器)");
        chain.doFilter(request, response);       
}

3.web.xml配置

  <!-- 配置第一个过滤器 -->
  <filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.zh.filter.MyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
    <!-- 配置第二个过滤器 -->
  <filter>
    <display-name>MyFilter2</display-name>
    <filter-name>MyFilter2</filter-name>
    <filter-class>com.zh.filter.MyFilter2</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter2</filter-name>
    <url-pattern>*.do</url-pattern>
  </filter-mapping>
  <!-- 配置第三个过滤器 -->
  <filter>
    <display-name>MyFilter3</display-name>
    <filter-name>MyFilter3</filter-name>
    <filter-class>com.zh.filter.MyFilter3</filter-class>
  </filter>

4.结果

浏览器:
http://localhost:8000/Filter/test.do
控制台:
MyFilter.doFilter(我被执行了)
MyFilter2.doFilter(我是第二个拦截器)
MyFilter3.doFilter(我是第三个拦截器)
TestServlet.service(我是servlet)
MyFilter.doFilter(我被执行了2)

注意: url-pattern:/* 表示拦截所有的请求。 url-pattern:*.do 表示所有以.do结尾的请求。一般是用来进行模块拦截处理。 url-pattern:/ts 表示拦截指定url的请求。针对某个servlet的请求进行拦截,保护servlet。

# 总结

过滤器的使用:

作用:对服务器接受的请求资源和响应给浏览器的资源进行管理。保护servlet

使用:创建一个实现了Filter接口的普通java类,覆写接口的方法

init方法:服务器启动即执行。资源初始化

doFilter方法:拦截请求的方法,在此方法中可以对资源实现管理。

注意:

需要手动对请求进行放行。chain.doFilter(request, response);

destory方法:服务器关闭执行。

在web.xml中配置过滤器

过滤器的生命周期:服务器启动到服务器关闭。

总结:过滤器程序员声明和配置,服务器根据请求中的uri信息调用。

执行: 浏览器发起请求到服务器,服务器接收到请求后,根据URI信息在web.xml中找到对应的过滤器执行doFilter方法,该方法对此次请求进行处理后如果符合要求则放行,放行后,如果还有符合要求的过滤则继续进行过滤,找到执行对应的servlet进行请求处理。servlet对,请求处理完毕后,也就service方法结束了。还需继续返回相应的doFilter方法继续执行。

# 统一编码设置和session管理

统一编码

//设置编码格式
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;chartset=utf-8");

session管理

//session管理
HttpSession hs = ((HttpServletRequest)request).getSession();
if(hs.getAttribute("user")==null) {
    ((HttpServletResponse)response).sendRedirect("/Filter/login.jsp");
}else {
    //放行
    chain.doFilter(request, response);
}

注意:

filter下的request来自javax.servlet接口 servlet下的request来自javax.servlet.http接口是filter的子接口,需要向下转型 HttpSession hs = ((HttpServletRequest)request).getSession();

public class MyFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器被初始化了");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        //设置编码格式
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;chartset=utf-8");
        //session管理
        //javax.servlet.http.HttpServletRequest;
        HttpSession hs = ((HttpServletRequest)request).getSession();
        if(hs.getAttribute("user")==null) {
            ((HttpServletResponse)response).sendRedirect("/Filter/login.jsp");
        }else {
            //放行
            chain.doFilter(request, response);
        }
    }
    @Override
    public void destroy() {
        System.out.println("过滤器被销毁了");
    }
}