过滤器:基本功能就是对Servlet的调用过程进行拦截,从而在Servlet处理请求和响应的时候增加一些特定的功能。
常见的Filter 实现的功能有,URL级别的权限访问控制、过滤敏感词汇、压缩响应星系、设置POST方式得同意编码。
程序中的过滤器理解角度可以比喻为生活中得自来水。可以将水肿得杂志。有害物质等进行过滤。
当客户端向服务器中的资源发出请求时,会先被过滤器Filter进行拦截处理,之后再将处理后的请求转发给真正的服务器资源,此外服务器接受到的请求并给出响应,响应会先回被过滤器拦截处理,之后再将处理后的响应转发给客户端,及在请求和响应的过程前,都会被过滤器进行拦截处理。
- 而在程序中的过滤器,实际就是实现了javax.servlet.Filter 接口的类,javax.servlet.Filter接口中定义了以下3个方法:
- void init(FilterConfig conf): 执行过滤初始化,Web容器会在web项目启动的时候,自动调用该方法。
- void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 当请求和响应拦截后,就通过doFilter方法来处理,request参数就是拦截得请求对象,可以使用FilterChain参数的doFilter方法讲拦截得请求和响应释放。
- void destroy() 用于释放或关闭Filter 对象打开的资源,如数据库、关闭IO流等操作,在Web项目关闭时候,由Web容器自动调用该方法。
Filter 得init()和destroy()方法鸽子只会被调用一次,而doFilter方法会在每次客户发出请求时候被调用。
init方法里的FilterConfig参数,主要为过滤器提供初始化参数。
FilterConfig是一个接口,常使用的方法如下:
- String getFilterName() 获取web.xml 中过滤器得名称
- String getInitParameter(String param):获取web.xml 中参数名对应的参数值
- ServletContext getServletContext(): 获取web.xml应用程序的ServletContext
第一个Filter程序
创建Servlet
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("doGet…");
}
…
}
在web.xml中配置此Servlet
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>
MyServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>MyFirstFilter</filter-name>
<filter-class>
MyFirstFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFirstFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
上面既配置了Servlet,也配置累当访问这个Servlet 得Filter,在访问这个Servlet之前,请求会被这个Filter拦截下。
Filter类
public class MyFirstFilter implements Filter{
@Override
public void init(FilterConfig arg0) throws ServletException{
System.out.println("过滤器01的初始化init()方法...");
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException{
System.out.println("过滤器01的执行方法:doFilter()方法...");
}
@Override
public void destroy(){
System.out.println("过滤器01的销毁destory()方法...");
System.out.println("拦截请求01...");
chain.doFilter(request, response);
System.out.println("拦截响应01...");
}
}
Filter中的配置方法和Servlet中的配置方法类似,先通过<url-pattern> 匹配腰拦截得请求,在根据<filter-name>找到对应的过滤器中处理类<filter-class>,最后执行过滤类中的init()、doFilter()
、destroy()
等方法。
上面的方法中使用 chain.doFilter(request, response);得作用就是将拦截器处理之后将其释放掉,交给下个Filter或者到达Servlet去处理,而在doFilter之前处理的就是拦截器请求时执行的代码,而之后的代码就是拦截器响应执行的代码。
Filter 得映射
web.xml中的<url-pattern>元素来配置需要拦截得请求,如果是这样的配置
<url-pattern>/*</url-pattern> 表示拦截项目中所有的请求。
<url-pattern>/*.do</url-pattern> 拦截所有的以.do 结尾的请求。
Filter链,就是为如下所示
<filter>
<filter-name>MyFirstFilter</filter-name>
<filter-class>
MyFirstFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFirstFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>MySecondFilter</filter-name>
<filter-class>
MySecondFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>MySecondFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
构建多个Filter,Filter 得顺序是根据以上配置的顺序执行的。
拦截请求:请求先被MyFirstFilter拦截,再被MySecondFilter拦截;
拦截响应:与拦截请求的顺序正好相反:即响应先被MySecondFilter拦截,再被MyFirstFilter拦截
监听器
在Web应用程序的运行期间,Web容器会创建和销毁四个对象:ServletContext
、HttpSession
、ServletRequest
、PageContext
,这些对象被称为“域对象”(除了PageContext
以外,Servlet API为其他三个域对象都提供了各自的监听器,用来监听它们的行为。
ervlet API提供了ServletContextListener
、HttpSessionListener
、ServletRequestListener
三个监听器接口,用来分别监听ServletContext
、HttpSession
、ServletRequest
三个域对象。当这三个域对象创建或销毁时,就会自动触发相应的监听器接口。
ServletContextListener
接口可以用来监听ServletContext
域对象的创建、销毁过程。当在Web应用程序中注册了一个或多个实现了ServletContextListener
接口的事件监听器时,Web容器就会在创建、销毁每个ServletContext
对象时都产生一个相应的事件对象,然后依次调用每个ServletContext
事件监听器中的处理方法,并将产生的事件对象传递给这些方法来完成事件的处理工作。