直接学习SSH虽然立竿见影,但是不如脚踏实地的学习JavaWeb的一些基础内容,毕竟SSH相关的内容总是绕不开基础的东西。
前面的文章叙述了Servlet的相关内容,这章将叙述Servlet中的Filter内容,该内容会在Struts中反复使用。
Filter:中文名为过滤器。
作用:开发人员通过Filter可以对web服务器的资源进行管理,例如Jsp,Servlet, 静态图片文件等进行拦截,从而实现一些特殊的功能。
例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能
若想创建一个Filter类,需要实现Filter接口,即显式实现API提供的Filter接口,只要实现了该接口,这个java类就为过滤器类。
这个类就可以让用户在访问某个目标资源之前,对访问的请求和响应进行拦截。
Filter源码:
public interface Filter { public void init(FilterConfig filterConfig) throws ServletException; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; public void destroy(); }
该接口和Servlet类似,都有一个初始化方法、销毁方法,执行方法,只不过httpServlet里面的执行方法是Service,这个里面是doFilter。
HttpService中的service方法的作用:每次执行url请求时,都会执行一次service方法。
doFilter方法的作用:在url请求想要获取目标资源前,或调用目标后,以及是否调用资源目标,都要执行一次doFilter方法对其进行处理。
doFilter中的ServletRequest/ServletResponse声明是接口,并非实现类,而传递给我们的request、Response参数可以是该接口的实现类。
我们这里主要用到FilterChain接口的doFilter这个方法,这个参数决定目标资源是否可以被访问。
FilterChain是一个接口,该接口里面只有一个方法,其代码如下:
public interface FilterChain { public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException; }什么意思呢?
假如我们编写了Filter的实现类FilterA,然后FilterA实现了Filter接口的doFilter方法,接下来doFilter方法里面的FilterChain可以从doFilter方法里形参中获取其ServletRequest和ServletResopnse参数,再执行doFilter方法。
FilterChain接口的doFilter方法会调用servlet的service方法,
代码如下:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class FilterTest implements Filter{ public void destroy() { System.out.println("----Filter销毁----"); } public void doFilter(ServletRequest request, ServletResponse response,FilterChain filterChain) throws IOException, ServletException { // 对request、response进行一些预处理 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); System.out.println("----调用service之前执行一段代码----"); filterChain.doFilter(request, response); // 执行目标资源,放行 System.out.println("----调用service之后执行一段代码----"); } public void init(FilterConfig arg0) throws ServletException { System.out.println("----Filter初始化----"); } }web.XML
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" 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_3_0.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!--配置过滤器--> <filter> <filter-name>FilterA</filter-name> <filter-class>com.filter.FilterA</filter-class> </filter> <!--映射过滤器--> <filter-mapping> <filter-name>FilterA</filter-name> <!--“/*”表示拦截所有的请求 --> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>我们将web.xml和FilterA结合起来:
先在web.xml中声明了一个过滤器,该过滤器命名为FilterA,其路径为com.filter.FilterA,至于FilterA怎么被web服务器创建的,无需知道,只需要知道是tomcat通过反射创建的即可。
然后又在web.xml里面写了一个过滤器表,该表表示有哪些过滤器,以及过滤器要过滤那些请求,一般的我们都拦截所以请求,学过Struts2的会发现,这里很类似。
当一个url请求经过我们的过滤器FilterA时,过滤器的doFilter拦截到了。
我们将在doFilter方法中进行处理,我们可以获取到request中得相关数据,也可以获取到response中的相关数据。
如果request中获取到的数据和我们所要的一样,就要执行 filterChain.doFilter(request, response); 语句,该语句会直接跳转到HttpServlet的实现类的Service方法里。
在这之前,你如果不调用该方法,他就走不到Servlet的Service这里,换句话说,接下来就不会执行servlet的Service方法。
跳转到Service方法里面后,然后就会执行Servlet的doget和dopost方法。
执行完Servlet的相关方法后,就执行ilterChain.doFilter(request, response);语句后面的语句。
所以他的执行顺序是:
Filter的init()方法,Filter的doFilter()方法,doFilter()方法里面的FilterChain接口的doFilter方法,
Servlet的init()方法,Servlet的doService()方法,Servlet的doget()方法,Servlet的dopost()方法
doFilter()方法里面的剩余语句。
Filter的destroy方法,不明白Servlet看我的Servlet概述。
对上述进行总结(即Filter的功能):
在servlet被调用之前截获;
在servlet被调用之前检查servlet request;
根据需要修改request头和request数据;
根据需要修改response头和response数据;
在servlet被调用之后截获.