zoukankan      html  css  js  c++  java
  • javaWeb学习总结(10)- Filter(过滤器)常见应用(3)

    一、统一全站字符编码

      通过配置参数charset指明使用何种字符编码,以处理Html Form请求参数的中文问题

    package me.gacl.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;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    
    /**
    * @ClassName: CharacterEncodingFilter
    * @Description: 此过滤器用来解决全站中文乱码问题
    * @author: 孤傲苍狼
    * @date: 2014-8-31 下午11:09:37
    *
    */ 
    public class CharacterEncodingFilter implements Filter {
    
        private FilterConfig filterConfig = null;
        //设置默认的字符编码
        private String defaultCharset = "UTF-8";
    
        public void doFilter(ServletRequest req, ServletResponse resp,
                FilterChain chain) throws IOException, ServletException {
            
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
            String charset = filterConfig.getInitParameter("charset");
            if(charset==null){
                charset = defaultCharset;
            }
            request.setCharacterEncoding(charset);
            response.setCharacterEncoding(charset);
            response.setContentType("text/html;charset="+charset);
            
            MyCharacterEncodingRequest requestWrapper = new MyCharacterEncodingRequest(request);
            chain.doFilter(requestWrapper, response);
        }
    
        public void init(FilterConfig filterConfig) throws ServletException {
            //得到过滤器的初始化配置信息
            this.filterConfig = filterConfig;
        }
        
        public void destroy() {
    
        }
    }
    
    /*
    1.实现与被增强对象相同的接口 
    2、定义一个变量记住被增强对象
    3、定义一个构造器,接收被增强对象
    4、覆盖需要增强的方法
    5、对于不想增强的方法,直接调用被增强对象(目标对象)的方法
     */
     
    class MyCharacterEncodingRequest extends HttpServletRequestWrapper{
        
        private HttpServletRequest request;
        public MyCharacterEncodingRequest(HttpServletRequest request) {
            super(request);
            this.request = request;
        }
        /* 重写getParameter方法
         * @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String)
         */
        @Override
        public String getParameter(String name) {
            
            try{
                //获取参数的值
                String value= this.request.getParameter(name);
                if(value==null){
                    return null;
                }
                //如果不是以get方式提交数据的,就直接返回获取到的值
                if(!this.request.getMethod().equalsIgnoreCase("get")) {
                    return value;
                }else{
                    //如果是以get方式提交数据的,就对获取到的值进行转码处理
                    value = new String(value.getBytes("ISO8859-1"),this.request.getCharacterEncoding());
                    return value;
                }
            }catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    web.xml文件中的配置如下:

    <filter>
          <filter-name>CharacterEncodingFilter</filter-name>
          <filter-class>me.gacl.web.filter.CharacterEncodingFilter</filter-class>
          <init-param>
              <param-name>charset</param-name>
              <param-value>UTF-8</param-value>
          </init-param>
      </filter>
      
      <filter-mapping>
          <filter-name>CharacterEncodingFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>

    二、禁止浏览器缓存所有动态页面

      有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秒。
    package me.gacl.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;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
    * @ClassName: NoCacheFilter
    * @Description: 禁止浏览器缓存所有动态页面
    * @author: 孤傲苍狼
    * @date: 2014-8-31 下午11:25:40
    *
    */ 
    public class NoCacheFilter implements Filter {
    
    
        public void doFilter(ServletRequest req, ServletResponse resp,
                FilterChain chain) throws IOException, ServletException {
            //把ServletRequest强转成HttpServletRequest
            HttpServletRequest request = (HttpServletRequest) req;
            //把ServletResponse强转成HttpServletResponse
            HttpServletResponse response = (HttpServletResponse) resp;
            //禁止浏览器缓存所有动态页面
            response.setDateHeader("Expires", -1);
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Pragma", "no-cache");
            
            chain.doFilter(request, response);
        }
    
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
        
        public void destroy() {
            
        }
    }

    web.xml文件中的配置如下:

    <filter>
          <filter-name>NoCacheFilter</filter-name>
          <filter-class>me.gacl.web.filter.NoCacheFilter</filter-class>
      </filter>
      
      <filter-mapping>
          <filter-name>NoCacheFilter</filter-name>
            <!--只拦截Jsp请求-->
          <servlet-name>*.jsp</servlet-name>
      </filter-mapping>

    三、控制浏览器缓存页面中的静态资源

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

    package me.gacl.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;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
    * @ClassName: CacheFilter
    * @Description: 控制缓存的filter
    * @author: 孤傲苍狼
    * @date: 2014-9-1 下午9:39:38
    *
    */ 
    public class CacheFilter implements Filter {
    
        private FilterConfig filterConfig;
    
        public void doFilter(ServletRequest req, ServletResponse resp,
                FilterChain chain) throws IOException, ServletException {
        
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
            
            //1.获取用户想访问的资源
            String uri = request.getRequestURI(); 
            
            //2.得到用户想访问的资源的后缀名
            String ext = uri.substring(uri.lastIndexOf(".")+1);
            
            //得到资源需要缓存的时间
            String time = filterConfig.getInitParameter(ext);
            if(time!=null){
                long t = Long.parseLong(time)*3600*1000;
                //设置缓存
                response.setDateHeader("expires", System.currentTimeMillis() + t);
            }
            
            chain.doFilter(request, response);
    
        }
    
        public void init(FilterConfig filterConfig) throws ServletException {
            this.filterConfig = filterConfig;
        }
        
        public void destroy() {
            
        }
    }

    web.xml文件中的配置如下:

    <!-- 配置缓存过滤器 -->
       <filter>
          <filter-name>CacheFilter</filter-name>
          <filter-class>me.gacl.web.filter.CacheFilter</filter-class>
           <!-- 配置要缓存的web资源以及缓存时间,以小时为单位 -->
          <init-param>
              <param-name>css</param-name>
              <param-value>4</param-value>
          </init-param>
          <init-param>
              <param-name>jpg</param-name>
              <param-value>1</param-value>
          </init-param>
          <init-param>
              <param-name>js</param-name>
              <param-value>4</param-value>
          </init-param>
          <init-param>
              <param-name>png</param-name>
              <param-value>4</param-value>
          </init-param>
      </filter>
      <!-- 配置要缓存的web资源的后缀-->
      <filter-mapping>
          <filter-name>CacheFilter</filter-name>
          <url-pattern>*.jpg</url-pattern>
      </filter-mapping>
      
      <filter-mapping>
          <filter-name>CacheFilter</filter-name>
          <url-pattern>*.css</url-pattern>
      </filter-mapping>
      
      <filter-mapping>
          <filter-name>CacheFilter</filter-name>
          <url-pattern>*.js</url-pattern>
      </filter-mapping>
       <filter-mapping>
          <filter-name>CacheFilter</filter-name>
          <url-pattern>*.png</url-pattern>
      </filter-mapping>

    四、实现用户自动登陆

      思路是这样的:

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

      核心代码如下:

      处理用户登录的控制器:LoginServlet

    package me.gacl.web.controller;
    
    import java.io.IOException;
    
    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 me.gacl.dao.UserDao;
    import me.gacl.domain.User;
    import me.gacl.util.WebUtils;
    
    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");
            
            UserDao dao = new UserDao();
            User user = dao.find(username, password);
            if(user==null){
                request.setAttribute("message", "用户名或密码不对!!");
                request.getRequestDispatcher("/message.jsp").forward(request, response);
                return;
            }
            request.getSession().setAttribute("user", user);
            //发送自动登陆cookie给客户端浏览器进行存储
            sendAutoLoginCookie(request,response,user);
            request.getRequestDispatcher("/index.jsp").forward(request, response);
        }
    
        /**
        * @Method: sendAutoLoginCookie
        * @Description: 发送自动登录cookie给客户端浏览器
        * @Anthor:孤傲苍狼
        *
        * @param request
        * @param response
        * @param user
        */ 
        private void sendAutoLoginCookie(HttpServletRequest request, HttpServletResponse response, User user) {
            if (request.getParameter("logintime")!=null) {
                int logintime = Integer.parseInt(request.getParameter("logintime"));
                //创建cookie,cookie的名字是autologin,值是用户登录的用户名和密码,用户名和密码之间使用.进行分割,密码经过md5加密处理
                Cookie cookie = new Cookie("autologin",user.getUsername() + "." + WebUtils.md5(user.getPassword()));
                //设置cookie的有效期
                cookie.setMaxAge(logintime);
                //设置cookie的有效路径
                cookie.setPath(request.getContextPath());
                //将cookie写入到客户端浏览器
                response.addCookie(cookie);
            }
        }
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
            doGet(request, response);
        }
    
    }

    处理用户自动登录的过滤器:AutoLoginFilter

    package me.gacl.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;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import me.gacl.dao.UserDao;
    import me.gacl.domain.User;
    import me.gacl.util.WebUtils;
    
    public class AutoLoginFilter implements Filter {
    
        public void doFilter(ServletRequest req, ServletResponse resp,
                FilterChain chain) throws IOException, ServletException {
            
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
            //如果已经登录了,就直接chain.doFilter(request, response)放行
            if(request.getSession().getAttribute("user")!=null){
                chain.doFilter(request, response);
                return;
            }
            
            //1.得到用户带过来的authlogin的cookie
            String value = null;
            Cookie cookies[] = request.getCookies();
            for(int i=0;cookies!=null && i<cookies.length;i++){
                if(cookies[i].getName().equals("autologin")){
                    value = cookies[i].getValue();
                }
            }
            
            //2.得到 cookie中的用户名和密码 
            if(value!=null){
                String username = value.split("\.")[0];
                String password = value.split("\.")[1];
                
                //3.调用dao获取用户对应的密码
                UserDao dao = new UserDao();
                User user = dao.find(username);
                String dbpassword = user.getPassword();
                
                //4.检查用户带过来的md5的密码和数据库中的密码是否匹配,如匹配则自动登陆
                if(password.equals(WebUtils.md5(dbpassword))){
                    request.getSession().setAttribute("user", user);
                }
            }
            
            chain.doFilter(request, response);
        }
        
        public void destroy() {
            
        }
    
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    }

    如果想取消自动登录,那么可以在用户注销时删除自动登录cookie,核心代码如下:

    package me.gacl.web.controller;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class CancelAutoLoginServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //移除存储在session中的user
            request.getSession().removeAttribute("user");
            //移除自动登录的cookie
            removeAutoLoginCookie(request,response);
            //注销用户后跳转到登录页面
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
    
        /**
        * @Method: removeAutoLoginCookie
        * @Description: 删除自动登录cookie,
        *     JavaWeb中删除cookie的方式就是新创建一个cookie,新创建的cookie与要删除的cookie同名,
        *     设置新创建的cookie的cookie的有效期设置为0,有效路径与要删除的cookie的有效路径相同
        * @Anthor:孤傲苍狼
        *
        * @param request
        * @param response
        */ 
        private void removeAutoLoginCookie(HttpServletRequest request, HttpServletResponse response) {
            //创建一个名字为autologin的cookie
            Cookie cookie = new Cookie("autologin","");
             //将cookie的有效期设置为0,命令浏览器删除该cookie
            cookie.setMaxAge(0);
            //设置要删除的cookie的path
            cookie.setPath(request.getContextPath());
            response.addCookie(cookie);
        }
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }

    以上就是过滤器的几个常见应用场景。

    转自 http://www.cnblogs.com/xdp-gacl/p/3948422.html

  • 相关阅读:
    hdu 1017 A Mathematical Curiosity 解题报告
    hdu 2069 Coin Change 解题报告
    hut 1574 组合问题 解题报告
    hdu 2111 Saving HDU 解题报
    hut 1054 Jesse's Code 解题报告
    hdu1131 Count the Trees解题报告
    hdu 2159 FATE 解题报告
    hdu 1879 继续畅通工程 解题报告
    oracle的系统和对象权限
    oracle 自定义函数 返回一个表类型
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4171643.html
Copyright © 2011-2022 走看看