JavaWeb-03-Servlet-14-过滤器接口(Filter接口)
1.介绍
- 【位置】:来自于Servlet规范下的接口,在Tomcat中存在于servlet-api.jar包中。
- 【实现类】:Filter接口实现类由开发人员提供,Http服务器不负责提供。
- 【特性】:Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截。
2.具体作用
- 拦截Http服务器,帮助Http服务器检测当前请求的合法性
- 拦截Http服务器,对当前请求进行增强操作
3.Filter接口实现类开发三步骤
- 创建一个Java类实现Filter接口。
- 重写Filter接口中的doFilter方法。
- 通过配置web.xml将过滤器接口实现类注册到Http服务器中。
4.演示过滤器接口的过滤功能
4.1演示流程
- 新建一个网站MyWeb。
- 将一张非常赤鸡的图片放在/web目录下。
- 在/web目录下新建一个前端页面index.html,通过该页面访问服务端的这张图片,需要携带年龄参数。
- 定义一个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请求方式特征;
- 不限制请求参数的数量
- 要求把请求参数放在Request body(请求体)中。
- 请求不会被缓存,也不会保留在浏览器的历史记录中
由于请求参数必须放进请求体中,当服务器接收到请求协议包时,Tomcat会委派请求对象把请求体中的二进制数据进行编译。
而请求对象默认的字符集是【ISO-8859-1】,不支持中文。每次读取请求参数前,都需要设置为utf-8。
当服务端有很多处理post请求的Servlet时,每次都需要设置字符编码,增加了开发难度。
这时我们就可以通过过滤器来简化操作。
- 设置过滤器,针对所有的Servlet请求,全部拦截。
- 在过滤器的doFilter方法内,通知拦截过来的当前请求对象使用【utf-8】字符集对请求体内的内容进行重新编辑。
如此,便不需要每次都重新设置了。
5.2演示增强操作
5.2.1演示流程
- 新建一个网站MyWeb。
- 创建两个Servlet接口实现类OneServlet和TwoServelt,全部重写doPost方法,以不通知请求对象用utf-8字符集方式对请求体中的参数进行重新编辑的前提下,读取请求体中的请求参数,并把请求参数打印在控制台上。
- 在/web目录下新建一个前端页面index.html,编写两个表单,分别以post方式访问OneServlet和TwoServlet。
- 创建一个过滤器接口实现类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四种拦截格式
-
要求Tomcat在调用某一个具体文件之前,调用OneFilter拦截
-
<url-pattern>/img/dog.jpg</url-pattern>
-
-
要求Tomcat在调用某一个文件夹下所有的资源文件之前,调用OneFilter拦截
-
<url-pattern>/img/*</url-pattern>
-
-
要求Tomcat在调用任意文件夹下某种类型文件之前,调用OneFilter拦截
-
<url-pattern>*.jpg</url-pattern>
-
-
要求Tomcat在调用任意资源文件之前,调用OneFilter拦截
-
<url-pattern>/*</url-pattern>
-