Java Web程序设计—— Servlet高级
Filter过滤器
什么是Filter
- 在开发中,通过浏览器访问服务器端的目标资源时,过滤器实现拦截功能。如果过滤器判断是合理的请求,就方形,允许访问目标资源。
- Filter在web应用中拦截的过程如下:
- Filter过滤器就是一个实现了javax.servlet.Filter接口的类,在接口中定义了三个方法:
- init方法:在过滤器对象被创建后,执行初始化方法
- doFilter方法:在这个方法里面实现拦截和放行
- destroy方法:在过滤器销毁后,执行
实现第一个Filter程序
步骤:
- 创建MyServlet,通过浏览器访问servlet资源
package chapter08;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyServlet
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().print("hello Filter");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
- 创建MyFilter,拦截访问servlet资源,如果要放行,执行doFilter方法
package chapter08;
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;
/**
* Servlet Filter implementation class MyFilter
*/
public class MyFilter implements Filter {
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 允许访问目标资源
chain.doFilter(request, response);
System.out.println("输出内容了,代表拦截响应");
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
拦截的具体配置,在web.xml配置如下:
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<filter>
根元素用于注册一个Filter<filter-name>
子元素用于设置Filter名称<filter-class>
子元素用于设置Filter类的完整名称<filter-mapping>
根元素用于设置一个过滤器所拦截的资源<url-pattern>
子元素用于匹配用户请求的URL
Filter映射
- 使用通配符“*”拦截所有的用户请求:
<url-pattern>
配置有三种形式:
- 完全目录匹配:比如/MyServlet
- 目录匹配:比如
/*
,/aa/*
代表拦截aa目录下的所有请求 - 扩展名匹配:比如
*.do
,*.action
,错误写法:/*.do
- 拦截不同方式的访问请求:
- REQUEST:当用户直接访问页面时,web容器将会调用过滤器
- INCLUDE:如果目标资源时通过RequestDispatcher的include()方法访问的,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
- FORWARD:如果目标资源时通过RequestDispatcher的forward()方法访问的,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
- ERROR:如果目标资源时通过声明式异常处理机制调用的,那么该过滤器将被调用
Filter链
- 在web项目中可以注册多个Filter程序,多个Filter程序对同一url请求进行拦截,那么这么多个Filter程序就成为Filter链。
- 步骤:
- 创建MyServlet
package chapter08;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyServlet
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().print("hello MyFilter----------<br/>");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
- 创建MyFilter01,拦截访问MyServlet请求
package chapter08;
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;
/**
* Servlet Filter implementation class MyFilter01
*/
public class MyFilter01 implements Filter {
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
response.getWriter().print("hello MyFilter01-------before<br/>");
chain.doFilter(request, response);
response.getWriter().print("hello MyFilter01-------after<br/>");
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
- 创建MyFilter02,拦截访问MyServlet请求
package chapter08;
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;
/**
* Servlet Filter implementation class MyFilter02
*/
public class MyFilter02 implements Filter {
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
response.getWriter().print("hello MyFilter02-----------before<br/>");
chain.doFilter(request, response);
response.getWriter().print("hello MyFilter02-----------after<br/>");
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
注:多个过滤器拦截他同一个请求,拦截的顺序和web.xml配置顺序有关,谁的配置在前,谁先实现拦截
FilterConfig接口
- FilterConfig是Filter的配置对象,作用用来获取与Filter相关的参数信息
- 常用的方法有: