直接学习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被调用之后截获.