0x01 环境搭配
如果还不会搭建jsp环境的可以按照下面的文章跟着搭建
Mac版IDEA创建maven web项目-详细过程: https://www.yuque.com/pmiaowu/gpy1q8/npv0fr
0x02 前言
作用:Filter也叫过滤器,通常配置在MVC、Servlet和JSP请求前面
常用于后端权限控制
统一的Http请求参数过滤
统一的XSS、SQL注入、SSRF
等等攻击检测的处理
前置操作-必须要做!!!!
1. 对准 webapp目录 右键
2. 标记 webapp目录 为 源码 根
0x03 配置Filter 与 基础例子
WebFilter类,可配置的属性有这些
0x03.1 通过注解
0x03.1.1 通过注解配置映射关系
通过注解可以直接在GlobalFilter.java完成配置这样就无需在web.xml配置映射了
常用配置项
参数: urlPatterns
作用: 配置要拦截的资源
以指定资源匹配,例如:"/hello.jsp"
以目录匹配,例如:"/Servlet/*"
以后缀名匹配,例如:"*.jsp"
通配符,拦截所有web资源,例如:"/*"
例子:
@WebFilter(
// 过滤器的名字
// 一般来说保持和类名一致即可
filterName = "/GlobalFilter",
// 拦截所有web资源
urlPatterns = "/*")
public class GlobalFilter implements Filter {
参数: initParams
作用: 配置初始化参数
例子:
@WebFilter(
// 过滤器的名字
// 一般来说保持和类名一致即可
filterName = "/GlobalFilter",
// 初始化的参数,这里初始化了两个
initParams = {
@WebInitParam(name = "origin", value = "@WebFilter"),
@WebInitParam(name = "testName", value = "testValue")
})
public class GlobalFilter implements Filter {
参数: dispatcherTypes
作用: 配置拦截的类型,可配置多个
默认为DispatcherType.REQUEST
其中DispatcherType是个枚举类型,有下面几个值
FORWARD //转发的
INCLUDE //包含在页面的
REQUEST //请求的
ASYNC //异步的
ERROR //出错的
例子:
@WebFilter(
filterName = "/GlobalFilter",
// 设置拦截
dispatcherTypes = {
DispatcherType.REQUEST,
DispatcherType.ASYNC,
DispatcherType.ERROR
})
public class GlobalFilter implements Filter {
0x03.1.1 通过注解运行-例子
在这目录: src->main->webapp->com->Filter
创建一个文件: GlobalFilter.java
创建完毕以后GlobalFilter.java需要实现了Filter接口,并实现了3个方法
这3个方法的作用已经在注释中写清楚了
package com.Filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;
@WebFilter(
filterName = "/GlobalFilter",
urlPatterns = "/*",
initParams = {
@WebInitParam(name = "origin", value = "@WebFilter"),
@WebInitParam(name = "testName", value = "testValue")
},
dispatcherTypes = {
DispatcherType.REQUEST,
DispatcherType.INCLUDE,
DispatcherType.FORWARD,
DispatcherType.ERROR,
DispatcherType.ASYNC})
public class GlobalFilter implements Filter {
/**
* web 应用程序启动时
* web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能
* 从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)
* 开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象
*
* @param config
* @throws ServletException
*/
@Override
public void init(FilterConfig config) throws ServletException {
// 获取初始化参数
String origin = config.getInitParameter("origin");
String testName = config.getInitParameter("testName");
// 输出初始化参数
System.out.println("GlobalFilter类起源: " + origin);
System.out.println("GlobalFilter类testName值: " + testName);
}
/**
* 该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法
*
* @param request 当前请求
* @param response 当前响应
* @param chain 用于访问后续过滤器
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 输出站点名称
response.setCharacterEncoding("GBK");
response.getWriter().println("我是全局过滤器: GlobalFilter类");
// 允许访问目标资源,简称 放行
chain.doFilter(request, response);
}
/**
* Filter容器在销毁过滤器实例前调用该方法
*/
@Override
public void destroy() {
System.out.println("GlobalFilter类,被摧毁了");
}
}
创建好GlobalFilter.java以后
这边设置的是 拦截所有web资源 urlPatterns = "/*"
启动项目以后,任意访问个文件即可
例如: http://127.0.0.1:8081/mavenJspTest_war/index.jsp
0x03.2 通过web.xml
0x03.2.1 通过web.xml配置映射关系
通过在web.xml也可以很方便的完成配置映射
打开 WEB-INF目录下的web.xml
最基础的样子如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
</web-app>
设置Filter
作用: 定义这个Filter等待其它程序调用
例如:
<filter>
<!-- 类名 -->
<filter-name>HelloFilter</filter-name>
<!-- 所在的包路径 -->
<filter-class>com.Filter.HelloFilter</filter-class>
</filter>
例子:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<!-- 类名 -->
<filter-name>HelloFilter</filter-name>
<!-- 所在的包路径 -->
<filter-class>com.Filter.HelloFilter</filter-class>
</filter>
</web-app>
常用配置项
标签: <url-pattern> </url-pattern>
作用: 配置要拦截的资源
以指定资源匹配,例如:"/hello.jsp"
以目录匹配,例如:"/Servlet/*"
以后缀名匹配,例如:"*.jsp"
通配符,拦截所有web资源,例如:"/*"
注意: 设置了这个才会正常运行这个filter
例如:
<filter-mapping>
<!-- 与 <filter> 标签里面的 <filter-name> 字段保持一致 -->
<filter-name>HelloFilter</filter-name>
<!--拦截路径,表示拦截/TomcatTest这个目录的所有资源-->
<url-pattern>/TomcatTest/*</url-pattern>
</filter-mapping>
例子:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<!-- 类名 -->
<filter-name>HelloFilter</filter-name>
<!-- 所在的包路径 -->
<filter-class>com.Filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
<!-- 与 <filter> 标签里面的 <filter-name> 字段保持一致 -->
<filter-name>HelloFilter</filter-name>
<!--拦截路径,表示拦截/TomcatTest这个目录的所有资源-->
<url-pattern>/TomcatTest/*</url-pattern>
</filter-mapping>
</web-app>
标签: <init-param> </init-param>
作用: 配置初始化参数
例如:
<init-param>
<param-name>origin</param-name>
<param-value>web.xml</param-value>
</init-param>
例子:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<!-- 类名 -->
<filter-name>HelloFilter</filter-name>
<!-- 所在的包路径 -->
<filter-class>com.Filter.HelloFilter</filter-class>
<init-param>
<param-name>origin</param-name>
<param-value>web.xml</param-value>
</init-param>
<init-param>
<param-name>testName</param-name>
<param-value>testValue</param-value>
</init-param>
</filter>
</web-app>
标签: <dispatcher> </dispatcher>
作用: 配置拦截的类型,可配置多个
默认为DispatcherType.REQUEST
其中DispatcherType是个枚举类型,有下面几个值
FORWARD //转发的
INCLUDE //包含在页面的
REQUEST //请求的
ASYNC //异步的
ERROR //出错的
例如:
<dispatcher>REQUEST</dispatcher>
例子:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<!-- 类名 -->
<filter-name>HelloFilter</filter-name>
<!-- 所在的包路径 -->
<filter-class>com.Filter.HelloFilter</filter-class>
</filter>
<filter-mapping>
<!-- 与 <filter> 标签里面的 <filter-name> 字段保持一致 -->
<filter-name>HelloFilter</filter-name>
<!--拦截路径,表示拦截/TomcatTest这个目录的所有资源-->
<url-pattern>/TomcatTest/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
</web-app>
0x03.2.2 通过web.xml运行-例子
在这目录: src->main->webapp->com->Filter
创建一个文件: HelloFilter.java
在这目录: src->main->webapp->com->Filter
创建一个文件: HelloFilter.java
创建完毕以后HelloFilter.java需要实现了Filter接口,并实现了3个方法
package com.Filter;
import javax.servlet.*;
import java.io.IOException;
public class HelloFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
// 获取初始化参数
String origin = config.getInitParameter("origin");
String testName = config.getInitParameter("testName");
// 输出初始化参数
System.out.println("HelloFilter类起源: " + origin);
System.out.println("HelloFilter类testName值: " + testName);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 输出站点名称
response.setCharacterEncoding("GBK");
response.getWriter().println("站点网址:http://pmiaowu.phpoop.com");
// 允许访问目标资源,简称 放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("HelloFilter类,被摧毁了");
}
}
通过在web.xml也可以很方便的完成配置映射
打开 WEB-INF目录下的web.xml
修改为如下样子:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<!-- 类名 -->
<filter-name>HelloFilter</filter-name>
<!-- 所在的包路径 -->
<filter-class>com.Filter.HelloFilter</filter-class>
<init-param>
<param-name>origin</param-name>
<param-value>web.xml</param-value>
</init-param>
<init-param>
<param-name>testName</param-name>
<param-value>testValue</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- 与 <filter> 标签里面的 <filter-name> 字段保持一致 -->
<filter-name>HelloFilter</filter-name>
<!--拦截路径,表示拦截/TomcatTest这个目录的所有资源-->
<url-pattern>/TomcatTest/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<servlet>
<!-- 类名 -->
<servlet-name>HelloServlet</servlet-name>
<!-- 所在的包路径 -->
<servlet-class>com.Servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 与 <servlet> 标签里面的 <servlet-name> 字段保持一致 -->
<servlet-name>HelloServlet</servlet-name>
<!-- web访问的网址 -->
<url-pattern>/TomcatTest/HelloServlet</url-pattern>
</servlet-mapping>
</web-app>
创建好HelloFilter.java以后
这边设置的是拦截/TomcatTest这个目录的所有资源 <url-pattern>/*</url-pattern>
启动项目以后,任意访问带TomcatTest目录的即可
例如: http://127.0.0.1:8081/mavenJspTest_war/TomcatTest/HelloServlet
0x03.2.3 注意项
注意哦,web.xml拦截路径设置的是
<filter-mapping>
<!-- 与 <filter> 标签里面的 <filter-name> 字段保持一致 -->
<filter-name>HelloFilter</filter-name>
<!--拦截路径,表示拦截/TomcatTest这个目录的所有资源-->
<url-pattern>/TomcatTest/*</url-pattern>
</filter-mapping>
这表示只有URL中是/TomcatTest/xxxx的才会拦截
例如-拦截的: http://127.0.0.1:8081/mavenJspTest_war/TomcatTest/HelloServlet
例如-不拦截的: http://127.0.0.1:8081/mavenJspTest_war/HelloServlet
0x04 多个Filter的执行顺序
1. 在我们的请求到达Servle之间是可以经过多个Filter的
2. 使用注解的filter的执行顺序跟名称的字母顺序有关,例如AFilter会比BFilter先执行
3. 如果一定要确保执行顺序,那么建议使用web.xml声明Filter
4. 程序会最优先执行web.xml中配置的Filter
5. 在web.xml中,filter执行顺序跟<filter-mapping>的顺序有关,先声明的先执行