JavaWeb-03-Servlet-14-过滤器接口(Filter接口)

JavaWeb-03-Servlet-14-过滤器接口(Filter接口)

1.介绍

  1. 【位置】:来自于Servlet规范下的接口,在Tomcat中存在于servlet-api.jar包中。
  2. 【实现类】:Filter接口实现类由开发人员提供,Http服务器不负责提供。
  3. 【特性】:Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截。

2.具体作用

  1. 拦截Http服务器,帮助Http服务器检测当前请求的合法性
  2. 拦截Http服务器,对当前请求进行增强操作

3.Filter接口实现类开发三步骤

  1. 创建一个Java类实现Filter接口。
  2. 重写Filter接口中的doFilter方法。
  3. 通过配置web.xml将过滤器接口实现类注册到Http服务器中。

4.演示过滤器接口的过滤功能

4.1演示流程

  1. 新建一个网站MyWeb。
  2. 将一张非常赤鸡的图片放在/web目录下。
  3. 在/web目录下新建一个前端页面index.html,通过该页面访问服务端的这张图片,需要携带年龄参数。
  4. 定义一个Filter接口实现类,重写doFilter方法,在doFilter方法中对拦截到的请求参数进行过滤,将小于18岁的请求进行拦截。

4.2前端页面index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>查看图片</title>
</head>
<body>
    <center>
        <h1>点击查看赤鸡图片</h1>
        <form action="/MyWeb/非常赤鸡的图片.jpg" method="get">
            请输入年龄:<input type="text" name="age">
            <input type="submit" value="点击查看">
        </form>
    </center>
</body>
</html>

4.3过滤器接口实现类OneFilter

package com.tsccg.filter;

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Author: TSCCG
 * @Date: 2021/08/20 20:18
 */
public class OneFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        //1.通过拦截请求对象获取请求包中的请求参数,从而得知用户的真实年龄
        int age = Integer.parseInt(servletRequest.getParameter("age"));
        //2.根据年龄,帮助Http服务器判断本次请求是否合法
        if(age >= 18) {
            //将拦截的请求对象和响应对象放还给Http服务器,由Http服务器继续调用资源文件
            filterChain.doFilter(servletRequest,servletResponse);//放行
        } else {
            //过滤器代替Http服务器拒绝本次请求
            servletResponse.setContentType("text/html;charset=utf-8");
            PrintWriter out = servletResponse.getWriter();
            out.print("<center><font style='color:red;font-size:30px'>未成年人不得观看!</font></center>");
        }
    }
}

4.4注册过滤器接口实现类

通过配置/web/WEB_INF/web.xml文件,将过滤器接口实现类注册到服务器中

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 将过滤器类文件路径交给服务器   -->
    <filter>
        <filter-name>OneFilter</filter-name>
        <filter-class>com.tsccg.filter.OneFilter</filter-class>
    </filter>
    <!--  通知服务器在调用哪些资源文件时需要被当前过滤器拦截 -->
    <filter-mapping>
        <filter-name>OneFilter</filter-name>
        <url-pattern>/非常赤鸡的图片.jpg</url-pattern>
    </filter-mapping>
</web-app>

4.5开始演示

发布网站,开启服务器。

通过浏览器发送请求。

5.过滤器对拦截的请求作增强处理

5.1增强原理

post请求方式特征;

  1. 不限制请求参数的数量
  2. 要求把请求参数放在Request body(请求体)中。
  3. 请求不会被缓存,也不会保留在浏览器的历史记录中

由于请求参数必须放进请求体中,当服务器接收到请求协议包时,Tomcat会委派请求对象把请求体中的二进制数据进行编译。

而请求对象默认的字符集是【ISO-8859-1】,不支持中文。每次读取请求参数前,都需要设置为utf-8。

当服务端有很多处理post请求的Servlet时,每次都需要设置字符编码,增加了开发难度。

这时我们就可以通过过滤器来简化操作。

  1. 设置过滤器,针对所有的Servlet请求,全部拦截。
  2. 在过滤器的doFilter方法内,通知拦截过来的当前请求对象使用【utf-8】字符集对请求体内的内容进行重新编辑。

如此,便不需要每次都重新设置了。

5.2演示增强操作

5.2.1演示流程

  1. 新建一个网站MyWeb。
  2. 创建两个Servlet接口实现类OneServlet和TwoServelt,全部重写doPost方法,以不通知请求对象用utf-8字符集方式对请求体中的参数进行重新编辑的前提下,读取请求体中的请求参数,并把请求参数打印在控制台上。
  3. 在/web目录下新建一个前端页面index.html,编写两个表单,分别以post方式访问OneServlet和TwoServlet。
  4. 创建一个过滤器接口实现类OneFilter,将所有访问网站资源文件的请求进行拦截,通知拦截下来的请求对象使用utf-8字符集对请求体内的内容进行重新编辑。

5.2.2编写OneServelt和TwoServlet

OneServlet:

package com.tsccg.controller;

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

/**
 * @Author: TSCCG
 * @Date: 2021/08/20 22:23
 */
public class OneServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userName = request.getParameter("userName");
        System.out.println(userName);
    }
}

TwoServlet:

package com.tsccg.controller;

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

/**
 * @Author: TSCCG
 * @Date: 2021/08/20 22:23
 */
public class TwoServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //直接从请求体中读取参数
        String userName = request.getParameter("userName");
        System.out.println("TwoServlet从请求体获取到的参数:" + userName);
    }
}

5.2.3前端页面

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>发送post请求</title>
</head>
<body>
<center>
    <form action="/MyWeb/one" method="post">
        参数:<input type="text" name="userName"><br>
        <input type="submit" value="以POST方式请求访问OneServlet">
    </form>
    <form action="/MyWeb/two" method="post">
        参数:<input type="text" name="userName"><br>
        <input type="submit" value="以POST方式请求访问TwoServlet">
    </form>
</center>
</body>
</html>

5.2.4过滤器接口实现类

package com.tsccg.filter;

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

/**
 * @Author: TSCCG
 * @Date: 2021/08/20 22:42
 */
public class OneFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");//增强
        filterChain.doFilter(servletRequest,servletResponse);//归还
    }
}

5.2.5注册

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>OneServlet</servlet-name>
        <servlet-class>com.tsccg.controller.OneServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>TwoServlet</servlet-name>
        <servlet-class>com.tsccg.controller.TwoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>OneServlet</servlet-name>
        <url-pattern>/one</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>TwoServlet</servlet-name>
        <url-pattern>/two</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>OneFilter</filter-name>
        <filter-class>com.tsccg.filter.OneFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>OneFilter</filter-name>
        <!-- 通知Tomcat在调用所有资源文件之前,都需要调用OneFilter进行拦截 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

5.2.6开始演示

发布网站,通过浏览器发送请求

6.Filter拦截地址格式

6.1命令格式

<filter-mapping>
	<filter-name>OneFilter</filter-name>
    <url-pattern>拦截地址</url-pattern>
</filter-mapping>

6.2命令作用

拦截地址通知Tomcat在调用何种资源文件之前需要调用OneFilter过滤进行拦截。

6.3四种拦截格式

  1. 要求Tomcat在调用某一个具体文件之前,调用OneFilter拦截

    • <url-pattern>/img/dog.jpg</url-pattern>
      
  2. 要求Tomcat在调用某一个文件夹下所有的资源文件之前,调用OneFilter拦截

    • <url-pattern>/img/*</url-pattern>
      
  3. 要求Tomcat在调用任意文件夹下某种类型文件之前,调用OneFilter拦截

    • <url-pattern>*.jpg</url-pattern>
      
  4. 要求Tomcat在调用任意资源文件之前,调用OneFilter拦截

    • <url-pattern>/*</url-pattern>
      
posted @ 2021-08-20 23:20  TSCCG  阅读(238)  评论(0编辑  收藏  举报