心得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 { } }