1.Filter作用
拦截客户端对服务端的资源请求,如实现统一字符编码/禁止缓存/用户登录等
2.Filter的实现
开发Web应用时,实现了Servlet API接口中Filter接口的类就称为Filter过滤器类,然后在web.xml中配置和映射过滤器
3.执行过程
Web应用程序启动时,Web服务器负责创建Filter类,然后调用其init()方法进行初始化,准备拦截web.xml配置的过滤器地址 1)当请求被拦截时,首先执行相应FIlter类的doFilter()方法 2)当doFilter()中的过滤代码执行完成后,执行doFilter方法中chain参数的chain.doFilter()方法,此时服务器判断是否有其他的过滤器,如果有则执行另外的过滤器,如果没有则调用目标资源
4.配置
web.xml中配置Filter的格式如下:
<!--注册Filter--> <filter>
<filter-name>LoginFilter</filter-name> <filter-class>com.lpq.LoginFilter</filter-class> <init-param> <param-name>ignorePath</param-name> <param-value>/login</param-value> </init-param></filter> <!--映射Filter--> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
也可以在配置文件中配置多个Filter,执行的顺序取决于配置的顺序.服务器会将多个Filter组成一个过滤器链.Filter的doFilter()中有一个FilterChain类型的参数chain,当调用chain.doFilter()方法时,可系统判断过滤器链中是否存在其他的过滤器,如果有则继续执行其doFilter()方法,如果没有则调用目标资源
5.以登录为例
FIlter如下
@WebFilter(filterName = "LoginFilter")
public class LoginFilter implements Filter {
private Set<String> prefixIgnores=new HashSet<String>();
public void destroy() {
System.out.println("-----构造器销毁-----");
prefixIgnores=null;
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)resp;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
if(canIgnore(request)){
chain.doFilter(request,response); //执行目标资源
return;
}
String user=(String)request.getSession().getAttribute("username");
if(user!=null){
chain.doFilter(req,resp); //执行目标资源
}else{
RequestDispatcher rd=request.getRequestDispatcher("/index.jsp"); //转到用户登录页面
rd.forward(request,response);
}
}
public void init(FilterConfig config) throws ServletException {
System.out.println("-----过滤器初始化------");
//读取不需要过滤的url
String prefix=config.getServletContext().getContextPath();
String ignorePath=config.getInitParameter("ignorePath");
String[] ignoreArray=ignorePath.split(";");
for(String s:ignoreArray){
prefixIgnores.add(prefix+s);
}
}
private boolean canIgnore(HttpServletRequest request){
String requestUrl=request.getRequestURI();
for(String s:prefixIgnores){
if(requestUrl.startsWith(s))
return true;
}
return false;
}
}
LoginServlet
public class LoginServlet extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
response.setHeader("contentType","text/html;charset=UTF-8");
String user= request.getParameter("username");
String pwd=request.getParameter("password");
if(user.equals("admin") && pwd.equals("123456")){
//success
request.getSession().setAttribute("user",user);
RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/views/a.jsp");
rd.forward(request,response);
}else{
//fail
RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/views/b.jsp");
rd.forward(request,response);
}
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
}
}
web配置如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.lpq.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<!--注册Filter-->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.lpq.LoginFilter</filter-class>
<init-param>
<param-name>ignorePath</param-name>
<param-value>/login</param-value>
</init-param>
</filter>
<!--映射Filter-->
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>