心得2--Filter过滤器常见应用开发案例分页

     注意:关于相对路径与绝对路径的说法,大多数都是既可以使用相对路径又可以使用绝对路径;但是重定向例外,重定向只可以使用绝对路径。

1.Filter常见应用

2).禁止浏览器缓存所有动态页面的过滤器

有 3 个 HTTP 响应头字段都可以禁止浏览器缓存当前页面,它们在 Servlet 中的示例代码如下:

response.setDateHeader("Expires",-1);

response.setHeader("Cache-Control","no-cache"); 

response.setHeader("Pragma","no-cache"); 

并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头

Expires数据头:值为GMT时间值,为-1指浏览器不要缓存页面;Cache-Control响应头有两个常用值: no-cache指浏览器不要缓存当前页面;max-age:xxx指浏览器缓存页面xxx秒。

3).控制浏览器缓存页面中的静态资源的过滤器

场景:有些动态页面中引用了一些图片或css文件以修饰页面效果,这些图片和css文件经常是不变化的,所以为减轻服务器的压力,可以使用filter控制浏览器缓存这些文件,以提升服务器的性能。

4). 使用Filter实现URL级别的权限认证

情景:在实际开发中我们经常把一些执行敏感操作的servlet映射到一些特殊目录中,并用filter把这些特殊目录保护起来,限制只能拥有相应访问权限的用户才能访问这些目录下的资源。从而在我们系统中实现一种URL级别的权限功能。

要求:为使Filter具有通用性,Filter保护的资源和相应的访问权限通过filter参数的形式予以配置。

5). 实现用户自动登陆的过滤器

在用户登陆成功后,发送一个名称为user的cookie给客户端,cookie的值为用户名和md5加密后的密码。

编写一个AutoLoginFilter,这个filter检查用户是否带有名称为user的cookie来,如果有,则调用dao查询cookie的用户名和密码是否和数据库匹配,匹配则向session中存入user对象(即用户登陆标记),以实现程序完成自动登陆。

2. 回顾一下前面说过一些知识点都用着的必备内容:Filter的部署—注册Filter

<filter>

        <filter-name>testFitler</filter-name>

        <filter-class>org.test.TestFiter</filter-class>

        <init-param>

       <param-name>word_file</param-name>

       <param-value>/WEB-INF/word.txt</param-value>

        </init-param>

</filter>

<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空

<filter-class>元素用于指定过滤器的完整的限定类名

<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。

3.Filter的部署—映射Filter

<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径

<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字

<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)

<servlet-name>指定过滤器所拦截的Servlet名称

<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。

<dispatcher> 子元素可以设置的值及其意义

REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。

INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

4. Tip:Filter的部署—映射Filter示例

<filter-mapping>

     <filter-name>testFilter</filter-name>

    <url-pattern>/test.jsp</url-pattern>

</filter-mapping>

 

<filter-mapping>

    <filter-name>testFilter</filter-name>

   <url-pattern>/index.jsp</url-pattern>

   <dispatcher>REQUEST</dispatcher>

   <dispatcher>FORWARD</dispatcher>

</filter-mapping>

 

5. 一个实现用户自动登陆的过滤器的案例

这里只说主要类,那些辅助类就不一一列出了;下面是两个核心类

Servlet控制器LonginServlet.java

package com.csdn.web.servlet;

 

import java.io.IOException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.Date;

 

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

 

import com.csdn.dao.User1Dao;

import com.csdn.domain.User1;

 

public class LoginServlet extends HttpServlet {

 

   public void doGet(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

      

      String username = request.getParameter("username");

      String password = request.getParameter("password");

      int autoLoginTime = Integer.valueOf(request.getParameter("autoLoginTime"));

      

      User1Dao dao = new User1Dao();

      User1 user = dao.findUser(username, password);

      if(user!=null){

        request.getSession().setAttribute("user",user);

        

        Cookie cookie1 = new Cookie("username",user.getUsername());

        //密码加密

        String password1 = user.getPassword();

        String md5Password = md5(password1);

        Cookie cookie2 = new Cookie("password",md5Password);

        /*//设置不能通过手动修改本地时间而到达cookie不过期的漏洞

        Cookie cookie3 = new Cookie("currentTime",new Date()+"");

        cookie3.setMaxAge(autoLoginTime);*/

        cookie1.setMaxAge(autoLoginTime);

        cookie2.setMaxAge(autoLoginTime);

        cookie1.setPath("/filterDemo");

        cookie2.setPath("/filterDemo");

        //cookie3.setPath("/filterDemo");

        

        response.addCookie(cookie1);

        response.addCookie(cookie2);

        //response.addCookie(cookie3);

        

        response.sendRedirect("/filterDemo/welcome.jsp");

      }else{

        request.setAttribute("message","用户名或密码错误!");

        request.getRequestDispatcher("/message.jsp").forward(request, response);

      }

 

   }

   //用MD5对密码加密

   private String md5(String input){

      try {

        MessageDigest digest = MessageDigest.getInstance("md5");

        byte[] result = digest.digest(input.getBytes());

        BASE64Encoder encoder = new BASE64Encoder();

        return encoder.encode(result);

      } catch (NoSuchAlgorithmException e) {

        e.printStackTrace();

        throw new RuntimeException(e);

      }

      

   }

   public void doPost(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

      doGet(request, response);

   }

}

实现自动登陆的过滤器AutoLoginFilter.java

package com.csdn.web.filter;

 

import java.io.IOException;

import java.util.Date;

 

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import com.csdn.dao.User1Dao;

import com.csdn.domain.User1;

 

publicclass AutoLoginFilter implements Filter {

 

   @Override

   publicvoid destroy() {

   }

 

   @Override

   publicvoid doFilter(ServletRequest request, ServletResponse response,

        FilterChain chain) throws IOException, ServletException {

      

      HttpServletRequest req = (HttpServletRequest) request;

      HttpServletResponse resp = (HttpServletResponse) response;

      //1.检查用户是否登录

      User1 user = (User1) req.getSession().getAttribute("user");

      if(user!=null){

        chain.doFilter(req, resp);

        return;

      }

      //2.检查用户是否带cookielai

      Cookie[] cookies = req.getCookies();

      String username = null;

      String password = null;

      String currentTime = null;

      for(int i=0;cookies!=null&&i<cookies.length;i++){

        if(cookies[i].getName().equals("username")){

           username = cookies[i].getValue();

        }

        if(cookies[i].getName().equals("password")){

           password = cookies[i].getValue();

        }

        if(cookies[i].getName().equals("currentTime")){

            currentTime = cookies[i].getValue();

        }

      }

      if(username==null && password==null){

        chain.doFilter(req, resp);

        return;

      }

      /*//设置不能通过手动修改本地时间而到达cookie不过期的漏洞

      String autoLoginTime = request.getParameter("autoLoginTime");

      int current_old = Integer.parseInt(currentTime+autoLoginTime);

      int current_new = Integer.parseInt(new Date()+"");

      if(current_old>current_new){

        chain.doFilter(req, resp);

        return;

      }*/

      User1Dao dao = new User1Dao();

      User1 user1 = dao.findUser(username);

      String save_password = user1.getPassword();

      if(!password.equals(save_password)){

        chain.doFilter(req, resp);

      }

      req.getSession().setAttribute("user",user1);

      //最后一定不能忘了传给下一个过滤器或资源,否则会出错

      chain.doFilter(req, resp);

   }

 

   @Override

   publicvoid init(FilterConfig filterConfig) throws ServletException {

   }

 

}


 

 

posted @ 2012-12-04 18:56  yangkai_keven  阅读(248)  评论(0编辑  收藏  举报