JavaWeb——Filter

一、Filter简介
 Filter和Servlet一样默认都是单例的,Filter是请求到Servlet过程中的一个屏障,可以拦截和放行请求,像登录和注册这种请求若被拦截的话就无法登录和注册,也就无法执行一些需要登录后才能执行的操作了。
 Filter是JavaWeb中的三大组件(Servlet、Filter、Listener)之一,Filter直译过来叫过滤器,是用来过滤请求的,Filter虽不能过滤响应,但可以改变响应。
 Filter在JavaEE中实际上就是一个接口,我们可以实现这个接口达到一些目的。Filter的作用:
  1️⃣Filter可以在请求到达目标资源(JSP、Servlet、Html、CSS)之前拦截请求,并作相应处理
  2️⃣Filter可以放行请求,使请求到达目标资源
  3️⃣Filter可以在响应到达浏览器之前做一些处理

二、Filter的应用
 1、Filter的HelloWorld
  ①创建一个类并实现Filter接口

/**
 * HttpFilter 为Filter提供一个模板,其他Filter只需要继承HttpFilter即可
 * 
 * @author lenovo
 *
 */
public abstract class HttpFilter implements Filter {

	private FilterConfig filterConfig;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		this.init();
	}

	/**
	 * 该方法的目的是供子类重写,该方法会在服务器调用init(FilterConfig
	 * filterConfig)时被调用,以对Filter进行初始化操作
	 * 
	 * @throws ServletException
	 */
	public void init() throws ServletException {

	}

	/**
	 * 该方法定义为抽象方法,因为我们大多处理的是Http的请求,
	 * 因此将入参改为了HttpServletRequest和HttpServletResponse
	 * 
	 * @param req
	 * @param resp
	 * @param arg2
	 * @throws IOException
	 * @throws ServletException
	 */
	public abstract void doFilter(HttpServletRequest req, HttpServletResponse resp, FilterChain chain)
			throws IOException, ServletException;

	/**
	 * 服务器调用此方法时实现上会调用重写的doFilter(HttpServletRequest req, HttpServletResponse
	 * resp, FilterChain chain)
	 */
	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		this.doFilter(request, response, chain);
	}

	/**
	 * 通过该方法获取到filterConfig,继而可以获取到ServletContext,然后就可以获取配置文件中的参数
	 * 
	 * @return
	 */
	public FilterConfig getFilterConfig() {
		return filterConfig;
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}
}

  ②在web.xml文件中注册Filter:一个filter-mapping中可以配置多个url-pattern

<filter>
	<filter-name>别名</filter-name>
	<filter-class>全类名</filter-class>
</filter>
<filter-mapping>
	<filter-name>别名</filter-name>
	 <url-pattern>要拦截的地址</url-pattern>
</filter-mapping>

  示例:这种一个filter-mapping中配置多个url-pattern的方式不推荐,可以使用多个filter-mapping进行配置,见下例

<filter>
	<filter-name>HelloFilter</filter-name>
	<filter-class>com.bdm.filters.HelloFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>HelloFilter</filter-name>
	 <url-pattern>/index.jsp</url-pattern>
	 <url-pattern>/index.html</url-pattern>
</filter-mapping>

  示例:一个filter对应多个filter-mapping

<filter>  
    <filter-name>authority</filter-name>  
    <filter-class>com.bdm.filter.AuthorityFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>authority</filter-name>  
       <url-pattern>/pages/*</url-pattern>  
</filter-mapping>  
<filter-mapping>  
    <filter-name>authority</filter-name>  
    <url-pattern>/views/*</url-pattern>  
</filter-mapping>

 2、url-pattern的规则(同样适用于Servlet)
  url-pattern用来指定需要Filter拦截的请求的地址,有以下几种匹配的方式:
   1️⃣精确匹配:访问地址和url-pattern的地址要一模一样,Filter才会起作用,如/hello/1.jsp,只有访问项目根目录下的hello下的1.jsp时才会走Filter
   2️⃣路径匹配:访问的地址是在url-pattern的地址所配置的路径之下,Filter才会起作用,如/hello/*,只要访问项目根目录下的hello下的资源就会走Filter,因此/*会拦截发送到当前项目的所有请求
   3️⃣后缀匹配:访问的路径和url-pattern配置的后缀名一致时,Filter才会起作用,如*.abc,只要访问以.abc结尾的路径时,就会走Filter,*.jsp会拦截所有以jsp为后缀的请求
   我们所配置url-pattern必须符合以上规则,以上规则不可以混合使用,Servlet的url-pattern同样适用以上规则。

三、Filter的生命周期
 Filter的生命周期指的是Filter对象从被创建到被销毁的过程,与生命周期有关的方法:
  1、构造器:Filter的构造器在服务器一启动时就被调用,也就是说Filter的实例在服务器启动时就被创建。
  2、init()方法:init()在构造器调用之后马上被调用,用来做一些初始化操作,也是在服务器启动之后调用。服务器在调用init()方法时,会传过来一个FilterConfig对象,该对象的作用和ServletConfig差不多,封装了在web.xml中的配置信息,通过FilterConfig可以获取到Filter的别名,可以获取到当前Filter的初始化参数,可以获取到ServletContext对象,并通过ServletContext对象获取Filter全局配置参数信息:

servletContext.getInitParameter("paramName");

  3、doFilter()方法:doFilter()方法在Filter每次拦截请求时都会调用,是Filter中的主要方法,服务器在调用doFilter()方法时会传来这么几个参数:
  1️⃣ServletRequest:作用和Servlet中的一样,封装请求报文
  2️⃣ServletResponse:作用和Servlet中的一样,封装响应报文
  3️⃣FilterChain:该对象用来放行拦截的请求,放行方式为:

chain.doFilter(request,response);

  4、destroy()方法:destroy在项目卸载之前调用,用来在Filtert对象销毁之前做一些收尾工作

四、Filter的执行顺序
 我们可以为一个目标资源设置多个Filter,这样多个Filter就会组成一个Filter链。我们在Filter中调用chain.doFilter(),如果该Filter后还有Filter,就会接着调用下一个Filter的doFilter()方法。如果Filter的顺序是A->B->C,则拦截请求时的顺序就是A->B->C,而响应回到浏览器时的拦截顺序则是C->B->A。
 多个Filter的执行顺序是由什么决定的呢?
 Filter的执行顺序,是由web.xml中filter-mapping的配置顺序决定的,filter-mapping越靠前,越先执行,我们可以通过调整filter-mapping的顺序,来调整Filter的执行顺序(注意filter-mapping不能在对应的filter标签之前配置):

<!-- Servlet -->
<servlet>
	<servlet-name>HelloServlet</servlet-name>
	<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>HelloServlet</servlet-name>
	<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>

 当使用一个Filter去拦截一个Servlet时,将Filter的url-pattern和Servlet的url-pattern设置成一样的即可:

<filter-mapping>
	<filter-name>CFilter</filter-name>
	<url-pattern>/HelloServlet</url-pattern>
</filter-mapping>

 也可以在filter-mapping中设置一个servlet-name标签,将该标签设置为和要拦截的Servlet的name一致

<filter-mapping>
	<filter-name>CFilter</filter-name>
	<servlet-name>HelloServlet</servlet-name>
</filter-mapping>

五、Filter的dispatcher
 Filter默认只会拦截直接发送到目标资源的请求(request请求),而像转发之类的请求它是不会拦截的。如果希望Filter可以拦截转发到目标资源的请求,可以在filter-mapping中的dispatcher标签中配置:

<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>

 dispatcher有四个可选值:
  1️⃣REQUEST:指只会拦截直接发送到目标资源的请求,默认值,如果未配置dispatcher则默认就是该值,一旦指定了dispatcher则以指定的属性为准
  2️⃣FORWARD:会拦截所有通过转发来访问目标资源的请求
  3️⃣INCLUDE:会拦截所有通过动态包含访问目标资源的请求。静态包含<%@ include file=“目标文件”%>不会被拦截,动态包含<jsp:include page="/2.jsp"></jsp:include>会被拦截。只拦截动态包含而不拦截静态包含的原因:静态包含是直接将目标文件包含到原文件中,不需要编译等,而动态包含会在服务器中将jsp文件翻译为.class文件,相当于原页面向目标页面发送了一个请求
  4️⃣ERROR:会拦截在web.xml文件中配置的错误页面,可以据此指定一些错误码的错误页面,而不出现很丑的页面

<error-page>
	<error-code>404</error-code>
	<location>/2.jsp</location>
</error-page>

六、Filter的应用
 利用过滤器为请求和响应设置编码:这种设置编码的方式非常好,想改变编码的时候只需要修改配置文件即可
 步骤:
  ①在web.xml中配置编码方式:想改变编码方式时只需要修改value值即可

<context-param>
	<param-name>encode</param-name>
	<param-value>gbk</param-value>
</context-param>

  ②在Filter中为请求和响应设置编码:注意该Filter继承了上面的HttpFilter
在这里插入图片描述
  ③在web.xml中配置MyFilter,使其拦截项目中的所有请求

<filter>
	<filter-name>EncodingFilter</filter-name>
	<filter-class>com.bdm.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>EncodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值