web学习:web.xml使用:filter标签的使用

本文详细介绍了web.xml文件的作用及加载过程,重点讲解了filter标签的使用方法,并提供了实战代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

web学习:web.xml使用:filter标签的使用

1.认识web.xml

从零开始学习java web,学习web最开始就不得不说web.xml,以前只知道web.xml对web应用来说很重要,却不知道为什么,现在来记录下学习web.xml的标签。

web.xml的加载过程(引用)
在web-app元素内,元素的配置顺序与工程的加载顺序无关,web.xml的加载过程为:

1.启动一个web项目,web容器(如tomcat)读取web.xml文件,读取其中的配置信息
2.容器创建一个servlet上下文(servletContext),这个web项目所有部分共享这个上下文
3.容器将转换为键值对,交给servletContext
4.容器创建中的监听器实例
5.触发contextInitialized方法,listener被调用(当Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent 事件,该事件由ServletContextListener 来处理。ServletContextListener 接口中定义了处理ServletContextEvent 事件的两个方法contextInitialized;contextDestroyed,web.xml有contextLoaderListener监听器,spring等框架实现了本监听器的接口方法)
6.调用完contextInitialized方法后,容器再对filter初始化
7.容器对web.xml中的指定load-on-startup的值时,

1.当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet。
2.如果值小于0或未指定时,则表示只有在第一次请求的容器才在该servlet调用初始化函数(springMVC的初始化为此阶段。
3.正值越小,(优先级1,2,3...->递减)servlet的优先级越高,应用启动时就越先加载。
4.值相同时,容器就会自己选择顺序来加载。

1.1 filter标签

一般我们会在web.xml中见到如下的filter标签

		<filter>
    	<filter-name>MyFilter</filter-name>
    	<filter-class>web.xml.testFilter</filter-class>
    	<init-param>
       		<param-name>testfilter</param-name>
       		<param-value>我是测试过滤器</param-value>
	    </init-param>
    </filter>
    <filter-mapping>
    	<filter-name>MyFilter</filter-name>
    	<url-pattern>*.do</url-pattern>
    </filter-mapping>
1.1.1 filter-name标签中是我们声明一个filter的名字,其中MyFilter就是我声明的一个filter。
1.1.2 filter-class标签是我们什么的filter的全路径,该类需要实现filter接口(父类实现也可以)。
1.1.3 init-param是当容器初始化该filter时初始化的键值对,一个filter标签下可以定义多个,可以通过init方法的参数filterConfig.getInitParameter方法获取这些参数。
1.1.4 filter-mapping标签是定义外部访问路径的请求映射,此处我定义的是所有以 .do结尾的请求都将会被映射到MyFilter这个filter下。

总体配置大致是和servlet的配置是类似的,关于servlet和content-param的配置可以参考我的另一篇文章:https://blog.youkuaiyun.com/qq_17275841/article/details/88830334

1.2 简单使用

这些设置完之后我们就可以来看看这些标签到底是如何使用的:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<!-- xml配置  -->
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  	<context-param>
    	<param-name>myparam</param-name>
    	<param-value>我是context-param</param-value>
    </context-param>
    <servlet>
       <servlet-name>MyServlet</servlet-name>
       <servlet-class>web.xml.testServlet</servlet-class>
       <init-param>
       		<param-name>test</param-name>
       		<param-value>我是测试param</param-value>
	   </init-param>
	</servlet>
	<servlet-mapping>  
       <servlet-name>MyServlet</servlet-name>  
       <url-pattern>*.do</url-pattern>  
    </servlet-mapping>
    <filter>
    	<filter-name>MyFilter</filter-name>
    	<filter-class>web.xml.testFilter</filter-class>
    	<init-param>
       		<param-name>testfilter</param-name>
       		<param-value>我是测试过滤器</param-value>
	    </init-param>
    </filter>
    <filter-mapping>
    	<filter-name>MyFilter</filter-name>
    	<url-pattern>*.do</url-pattern>
    </filter-mapping>
</web-app>


//这里是我写的测试filter,对应web.xml中的 MyFilter
public class testFilter implements Filter {

	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("初始化filter");
		System.out.println(filterConfig.getServletContext().getInitParameter("myparam"));//输出context-param
		System.out.println(filterConfig.getInitParameter("testfilter"));//输出init-param
		System.out.println(filterConfig.getFilterName());//输出web.xml中定义的名字
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("调用filter");
		chain.doFilter(request, response);//此处不调用将无法进入配置的servlet
	}

	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("销毁filter");
	}

}

将程序用web容器跑起来,这里我用的是jetty,启动过程中的输出如下,filter在容器启动时就已经初始化了,会调用init方法

Running Jetty 6.1.26
2019-03-26 22:14:20.914:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
ParentLoaderPriority enabled
Context path:/spring
ProjectClassLoader: entry=D:\mydev\spring\target\classes
ProjectClassLoader: entry=D:\esendev\repository\junit\junit\3.8.1\junit-3.8.1.jar
ProjectClassLoader: entry=D:\esendev\repository\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar
2019-03-26 22:14:20.964:INFO::jetty-6.1.26
初始化filter
我是context-param
我是测试过滤器
MyFilter
2019-03-26 22:14:21.191:INFO::Started SelectChannelConnector@0.0.0.0:8081

在浏览器中访问 http://localhost:8081/spring/.do 以.do结尾的访问路径会先映射到该filter:

调用filter

初始化servlet
我是context-param
我是测试param
我是测试param

调用servlet
我是context-param
我是测试param
我是测试param

由于filter在容器启动时已经被初始化了,此时filter将只会调用dofilter方法,即第一行输出,在该方法中我们可以对请求过来的数据做过滤,比如它可以用来验证权限、加密和解密、Session检查等都可以在filter中执行。

1.3 踩坑指南

在dofilter方法中有个很重要的参数FilterChain 该参数的doFilter是用来转交给下一个filter或者servlet的,如果不调用,代码如下,访问 http://localhost:8081/spring/.do 时的输出将只输出调用filter,而不会进入web.xml中配置的servlet。


	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		System.out.println("调用filter");
		//chain.doFilter(request, response);//此处不调用将无法进入配置的servlet
	}
调用filter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值