过滤器

  过滤器相当于就是一个屏障,可以设置使所有请求都必须经过过滤器,然后才能访问资源。

  客户端→(←)过滤器→(←)被请求资源,不管是请求还是响应都必须经过过滤器,过滤器可以有无数个,只要有一个不让通过的话,那就通过不了。


一:如何写过滤器?

  (1)在com.kaishengit.web下建一个子包叫com.kaishengit.web.filter(这个是习惯性的,可选的)

  (2)写一个类,让该类实现javax.servlet.Filter接口

package com.kaishengit.web.filter;

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 New implements Filter{

    public void destroy() {
        
        
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        
    }

    public void init(FilterConfig filterConfig) throws ServletException {

    }

}

  所有的过滤器都得实现Filter方法,所以得实现方法里面的destroy()方法,init()方法,和doFilter()方法,但因为destroy()和init()一般比较少用,为了避免在每个过滤器中都实现这两个方法,可以写一个抽象类如AbstractFilter先实现Filter接口,然后让所有的过滤器都继承自这个抽象方法,这样在过滤器中只需要重写doFilter()方法即可,减少了代码量,这种设计模式叫做适配器模式。

  (3)在配置文件web.xml中配置Filter,如:

 <!--/*表示所有的文件都得经过过滤器,若是/.jspx,则只有 servlet文件需要经过过滤器-->

 <filter>
       <filter-name>LoginValidateFilter</filter-name>
       <filter-class>com.kaishengit.web.filter.LoginValidateFilter</filter-class>
   </filter>
   <filter-mapping>
       <filter-name>LoginValidateFilter</filter-name>
       <url-pattern>/*</url-pattern>        
   </filter-mapping>

  (4)容器启动时会初始化过滤器,此时构造方法和init()会被调用

 

二:过滤器的使用场景

  (1)表单输入的中文转码问题处理

package com.kaishengit.web.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class EncodingFilter extends AbstractFilter{
    //设置默认的字符集,避免用户忘了配置Filter文件设置字符集导致出现乱码
    private String encoding = "UTF-8";                   
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding(encoding);
        chain.doFilter(request,response);
    }
    

//从配置文件中取值,因为init()方法在服务器启动时就会调用,所以如果里面有值的话就将配置的字符集作为字符集,如果没有的话就使用默认的
    public void init(FilterConfig filterConfig) throws ServletException{      
        String value = filterConfig.getInitParameter("encoding");
        if(value != null && !"".equals(value)){
            encoding = value;
        }
    }
}

注:在配置文件中是这样配置的,这样是键为encoding,值为UTF-8,这样设置的原因是不把字符集写死,避免有些地区需要改的时候没法改。

  <filter>
       <filter-name>EncodingFilter</filter-name>
       <filter-class>com.kaishengit.web.filter.EncodingFilter</filter-class>
       <init-param>
           <param-name>encoding</param-name>

           <param-value>UTF-8</param-value>
       </init-param>
   </filter>

 

  (2)登陆验证

package com.kaishengit.web.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.kaishengit.entity.User;

public class LoginValidateFilter extends AbstractFilter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
      

   //将父类ServletRequest强制转换为子类HttpServletRequest,后面需要用到子类对象的属性

    HttpServletRequest request = (HttpServletRequest) req;          
        HttpServletResponse response = (HttpServletResponse) resp;
        

  //uri指的是所请求的相对路径,而url指的是绝对路径,queryString指的是最后面的参数,

   例:http://localhost/prod/prod.jspx?m=add,其中:http://localhost/prod/prod.jspx (绝对路径);

     /prod/prod.jspx(相对路径);m=add(后面的参数)
      

     String uri = request.getRequestURI();
        uri = uri.substring(uri.lastIndexOf("/")+1);
        
        String end = uri.substring(uri.lastIndexOf(".")+1);
        
        System.out.println("uri:"+uri);
        
        if("".equals(uri) || "index.jsp".equals(uri) || "login.jspx".equals(uri)){
            chain.doFilter(request, response);                        //若请求的是登陆页则直接放行
        } else if("js".equals(end) || "css".equals(end) || "html".equals(end) || "png".equals(end)){
            chain.doFilter(request, response);        //若请求的是以js,css,html,png等格式结尾的直接放行 
        }else {
            HttpSession session = request.getSession();
            User user = (User) session.getAttribute("User");
            
            if(user == null){
                //若是未登录用户访问,获取用户所想要访问的页面

      

      //因为request.getRequestURL()返回的是一个StringBuffer型,所以要加toString()
                String url = request.getRequestURL().toString();   
                
                String queryString = request.getQueryString();
                if(queryString != null){
                    url = url + "?" + queryString;
                }
                
                session.setAttribute("where", url);
                response.sendRedirect("login.jspx?code=10001");
                
            } else {
                //如果是已登录的用户,则直接放行
                chain.doFilter(request, response);
            }
        }
        
    }
    
}

posted on 2012-07-21 08:37  dongzhouzhou  阅读(306)  评论(0编辑  收藏  举报