过滤器Filter讲解-以及两种配置方式

文章目录

      • 1. 担任的角色
      • 2. 运行的流程
      • 3. 生命周期
      • 4. 三大过滤器核心接口
        • 4.1 Filter接口
        • 4.2 FilterConfig接口
        • 4.3 FilterChain接口
      • 5. 过滤器的使用
        • 5.1 代码实现
        • 5.2 声明配置
          • 5.2.1 注解@WebFilter
          • 5.2.2 配置文件web.xml
      • 6. 过滤器的应用场景
        • 6.1 设置请求、响应报文的编码
        • 6.2 控制用户权限 - 思路

1. 担任的角色

拦截请求、响应的作用 — 像小区的保安

过滤器Filter讲解-以及两种配置方式_第1张图片

2. 运行的流程

请求的预处理: 改变客户端请求的内容
响应的后处理: 改变Servlet、JSP等给用户的响应内容

作用功能: 设置用户访问权限、记录用户操作、对请求进行编码、压缩给客户端响应的资源

客户端 过滤器 服务器资源 1. 经过过滤器 1. 不经过过滤器 alt [ 请求匹配 ] [ 请求不匹配 ] 2. 可能经过过滤器修改的请求 2. 拒绝资源请求 alt [ 过滤器筛选通过 ] [ 过滤器筛选不通过 ] 3. 响应的资源 4. 可能经过过滤器修改的响应资源 客户端 过滤器 服务器资源

由上面的过滤器流程可知、一个服务器可能设置了多个过滤器,但一个请求并不需要经过一个服务器的所有过滤器,每个过滤器都有自己的过滤条件来进行请求过滤

3. 生命周期

服务器启动时
实例化顺序
实例化顺序
执行一次
请求、响应
服务器关闭时
生命周期
1. 过滤器加载、实例化
@WebFilter的filterName属性大小写顺序
Web.xml配置的声明顺序
2. 初始化init( FilterConfig )
3. 过滤doFilter()
4. 销毁destory()

4. 三大过滤器核心接口

Filter核心接口
Filter
FilterConfig
FilterChain

4.1 Filter接口

服务器用来实例化过滤器对象
对过滤器对象属性的赋值
请求、响应对象给下一个过滤器、目标资源
服务器用来结束、释放过滤器对象
Filter子类方法
无参构造函数
init( FilterConfig )
doFilter( request, response, FilterChain )
destory()

4.2 FilterConfig接口

获取过滤器的名字
获取某个配置属性的值
获取所有初始化参数的参数名
获取Servlet的上下文对象
FilterConfig方法
getFilterName()
getInitParameter( String )
getInitParameterNames()
getServletContext

4.3 FilterChain接口

请求分配给下一个过滤器、目标资源
FilterChain方法
doFilter( reuqest, response )

5. 过滤器的使用

1. 创建Filter接口实现类
2. 编写过滤器的功能接口
3. 对过滤器进行声明配置

5.1 代码实现

public class TestFilter implements Filter{
	
   public TestFilter() {
        System.out.println("实例化对象TestFilter()");
   }
   
   @Override
	public void init(FilterConfig fc) throws ServletException {
		System.out.println("初始化过滤器init(FilterConfig)");
        		//过滤器的配置参数在下面文章中
        String name = fc.getFilterName();
        String user = fc.getInitParameter("user");
        String Year = fc.getInitParameter("Year");
        String ParameterNames = Collections.list( fc.getInitParameterNames() ).toString();
        System.out.println(name + "\n" + user + "\n" + ParameterNames);
		Filter.super.init(fc);
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		System.out.println("过滤操作doFilter(req, resp, FilterChain)");
		 // 传给下一个过滤器,如果没有过滤器匹配,则直接访问资源
		chain.doFilter(request, response);
		
	}
	
   @Override
	public void destroy() {
		System.out.println("销毁过滤器destory()");
		Filter.super.destroy();
	}

}


  运行结果

Totmcat服务器启动时:输出
	实例化对象TestFilter(
	初始化过滤器init(FilterConfig)
    TestFilter1
    小明
    2019
    [year, user]
   
每次有向服务器请示时:输出
	过滤操作doFilter(req, resp, FilterChain)
	
Tomcat服务器关闭时:输出
	销毁过滤器destory()

5.2 声明配置

过滤器匹配的URL:urlPatterns + servletName( 注意这里是servletName不是servlet-class )

配置方法
Java源文件注解 @WebFilter
配置文件 web.xml
5.2.1 注解@WebFilter
数组
数组
数组
配置属性
filterName:过滤器名称 - 默认类名
urlPatterns、value:对请求的URL的匹配
servletNames:对哪些Servlet进行过滤
dispatcherTypes:请求模式的要求
request、forward、include、error、async
initParams:配置参数
@WebInitParam(name='', value='')
asynvSupport:是否支持异步操作
displayName:显示的名称
description:描述信息
dispatcherTypes - 数组
DispatcherType.REUQEST:客户端对服务器发起请求,过滤器才起作用
DispatcherType.FORWARD:请求分派对象.forward(),过滤器才起作用
DispatcherType.INCLUDE:请求分派对象.include(),过滤器才起作用
DispatcherType.ERROR:页面发生异常,跳转到新的页面,过滤器才起作用
DispatcherType.ASYNC:异步处理,过滤器才会起作用

urlPattern:*星号 只能是路径 或 文件类型匹配,不可以两者结合

  1. 路径匹配: http://localhost:8080/*
  2. 文件类型匹配: *.html
  3. 不可以: /*.html 或者 http://localhost:8080/*.jsp 等等


  注解示例

@WebFilter(
           urlPatterns = {"/index.jsp", "/login.jsp"},
           servletNames = { "TestServlet", "TestServlet2" },
           filterName = "TestFilter1",
           displayName = "TestFilter2",
           description = "TestFilter3",
           initParams = { 
                     @WebInitParam(name="user", value="小明"), 
                     @WebInitParam(name="year", value="2019")
           }
           dispatcherTypes = { DispatcherType.REUQEST, DispatcherType.FORWARD },
           asyncSupported = true           
)

5.2.2 配置文件web.xml
<servlet>
           <servlet-name>TestServletservlet-name>
           <servlet-class>top.linruchang.testServlet.TestServletservlet-class>
servlet>
<servlet-mapping>
           <servlet-name>TestServletservlet-name>
           <url-pattern>/test1.dourl-pattern>
servlet-mapping>

<filter>
		<filter-name>TestFilterfilter-name>
		<filter-class>top.linruchang.Filter.TestFilterfilter-class>
		<init-param>
			    <param-name>userparam-name>
			    <param-value>小明param-value>
		init-param>
		<init-param>
			    <param-name>yearparam-name>
			    <param-value>2019param-value>
		init-param>
filter>
<filter-mapping>
		<filter-name>TestFilter1filter-name>
		<url-pattern>*.jspurl-pattern>
		<servlet-name>TestServletservlet-name>
		<dispatcher>REQUESTdispatcher>
filter-mapping>

6. 过滤器的应用场景

应用
统一认证处理
对请求传递的参数进行处理:例数据库注入攻击
改变图像的格式
请求、响应的进行编码
响应内容进行压缩处理
XML → XSML进行输出转换

6.1 设置请求、响应报文的编码

不必在每个Servlet类中,每次都需要将request、response进行转码

@WebFilter(
    urlPatterns = { "/*" }
)
class  F_CharacterFilter implements Filter {
    private static String charset = "utf-8";
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {	
            String charset = filterConfig.getInitParameter("charset");
            if(charset!=null && charset=="") 
                TestFilter.charset = charset;
    }	

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {	
            request.setCharacterEncoding(charset);
            response.setCharacterEncoding(charset);
            chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
	
	}
 
}

6.2 控制用户权限 - 思路

过滤器判断当前请求会话中是否存在 有关用户信息的域属性,用这个域属性进行权限的控制

你可能感兴趣的:(Java,Tomcat)