Web笔记-Filter

1. 利用过滤器解决全站编码问题:
package cn.imeina.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 SetCharacterEncodingFilter implements Filter {
    /**
     * web.xml中该过滤器的配置参数
     */
    private FilterConfig fConfig;
    public SetCharacterEncodingFilter() {
    }
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
        //FilterConfig获取配置参数
        String encoding = fConfig.getInitParameter("encoding");
        if (encoding == null) {
            encoding = "UTF-8";
        }
        request.setCharacterEncoding(encoding);
        //更改字符流输出时的编码为UTF-8
        response.setCharacterEncoding(encoding);
        //更改字符流输出时的编码为UTF-8,同时通知浏览器以UTF-8编码显示
        response.setContentType("text/html;charset=" + encoding);
        chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
        
        this.fConfig = fConfig;
    }
}

web.xml中配置

  <filter>
      <filter-name>SetCharacterEncodingFilter</filter-name>
      <filter-class>com.gaoshiyi.web.filter.SetCharacterEncodingFilter</filter-class>
      <!-- 过滤器添加配置参数 -->
      <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>SetCharacterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

2. 控制动态资源禁止缓存过滤器
package cn.imeina.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;
public class DynamicResourceNoCacheFilter implements Filter {
    public DynamicResourceNoCacheFilter() {
        
    }
    public void destroy() {
        
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        
        //该段代码可以在HttpServlet源码中service方法中找到...
        HttpServletRequest req;
        HttpServletResponse resp;
        try {
            
            req = (HttpServletRequest) request;
            resp = (HttpServletResponse) response;
        } catch (Exception e) {
            throw new RuntimeException("non-http request or response");
        }
        //设置控制禁止缓存的三个响应头
        resp.setHeader("Expries", "-1");//HTTP1.0和1.1都有
        resp.setHeader("Cache-Control", "no-cache");//HTTP1.1
        resp.setHeader("Pragma", "no-cache");//HTTP1.0
        chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
        
    }
}

web.xml配置

    <filter>
        <filter-name>DynamicResourceNoCacheFilter</filter-name>
        <filter-class>com.gaoshiyi.web.filter.DynamicResourceNoCacheFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>DynamicResourceNoCacheFilter</filter-name>
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>
3. 控制静态资源时间缓存的过滤器
package cn.imeina.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;
public class StaticResourceNeedCacheFilter implements Filter {
    private FilterConfig fConfig;
    
    public StaticResourceNeedCacheFilter() {
    }
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        
        //该段代码可以在HttpServlet源码中service方法中找到...
        HttpServletRequest req;
        HttpServletResponse resp;
        try {
            
            req = (HttpServletRequest) request;
            resp = (HttpServletResponse) response;
        } catch (Exception e) {
            
            throw new RuntimeException("non-http request or response");
        }
        //根据用户访问的资源类型,读取配置文件设置指定资源的缓存时间
        String requestURI = req.getRequestURI();
        String cacheTime = "0";
        
        if (requestURI.endsWith(".html")) {
            //访问html资源
            cacheTime = fConfig.getInitParameter("html");
        }else if (requestURI.endsWith("css")) {
            //访问css资源
            cacheTime = fConfig.getInitParameter("css");
        }else if (requestURI.endsWith("js")) {
            //访问js资源
            cacheTime = fConfig.getInitParameter("js");
        }
        
        //设置静态资源缓存时间
        long time = Long.parseLong(cacheTime) * 60 * 60 * 1000;
        resp.setDateHeader("Expires", System.currentTimeMillis() + time);
        chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
        
        this.fConfig = fConfig;
    }
}

web.xml配置

    <filter>
        <filter-name>StaticResourceNeedCacheFilter</filter-name>
        <filter-class>com.gaoshiyi.web.filter.StaticResourceNeedCacheFilter</filter-class>
        <init-param>
            <param-name>html</param-name>
            <param-value>1</param-value>
        </init-param>
        <init-param>
            <param-name>css</param-name>
            <param-value>2</param-value>
        </init-param>
        <init-param>
            <param-name>js</param-name>
            <param-value>3</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>StaticResourceNeedCacheFilter</filter-name>
        <url-pattern>*.html</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>StaticResourceNeedCacheFilter</filter-name>
        <url-pattern>*.css</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>StaticResourceNeedCacheFilter</filter-name>
        <url-pattern>*.js</url-pattern>
    </filter-mapping>

4. 自动登录过滤器
package cn.imeina.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 javax.servlet.http.HttpSession;
import com.gaoshiyi.web.domain.User;
import com.gaoshiyi.web.service.BusinessService;
import com.gaoshiyi.web.service.impl.BusinessServiceImpl;
import com.gaoshiyi.web.utils.Base64;
public class AutoLoginFilter implements Filter {
    private BusinessService service = new BusinessServiceImpl();
    public AutoLoginFilter() {
    }
    public void destroy() {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 该段代码可以在HttpServlet源码中service方法中找到...
        HttpServletRequest req;
        HttpServletResponse resp;
        try {
            req = (HttpServletRequest) request;
            resp = (HttpServletResponse) response;
        } catch (Exception e) {
            throw new RuntimeException("non-http request or response");
        }
        HttpSession session = req.getSession();
        Object loginUser = session.getAttribute("user");
        if (loginUser == null) {// 未登录
            //获取Cookie并自动登录
            Cookie[] cookies = req.getCookies();
            for (int i = 0; cookies != null && i < cookies.length; i++) {
                if ("loginInfo".equals(cookies[i].getName())) {
                    String value = cookies[i].getValue();
                    String username = Base64.decode(value.split("\\_")[0]);
                    String password = value.split("\\_")[1];
                    User user = new User(username, password, null);
                    user = service.login(user);
                    if (user != null) {
                        session.setAttribute("user", user);
                        System.out.println("自动登录成功...");
                    }
                    break;
                }
            }
        }
        chain.doFilter(request, response);
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }
}
package com.gaoshiyi.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
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 javax.servlet.http.HttpSession;
import org.apache.commons.beanutils.BeanUtils;
import com.gaoshiyi.web.domain.User;
import com.gaoshiyi.web.service.BusinessService;
import com.gaoshiyi.web.service.impl.BusinessServiceImpl;
import com.gaoshiyi.web.utils.Base64;
/**
 * 控制器
 * @author AKid
 *
 */
public class ControllerServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    public ControllerServlet() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        String opt = request.getParameter("opt");
        if ("login".equals(opt)) {
            login(request, response);
        }
    }
    /**
     * 登录
     * @param request
     * @param response
     * @throws IOException 
     */
    private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        Map<String, String[]> map = request.getParameterMap();
        User user = new User();
        try {
            BeanUtils.populate(user, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        BusinessService service = new BusinessServiceImpl();
        User loginUser = service.login(user);
        if (loginUser == null) {
        
            response.getWriter().write("用户名或密码错误,请重新登录...");
            response.setHeader("refresh", "1,url=" + request.getContextPath() + "/login.jsp");
            return;
        }
        
        //判断用户是否为自动登录
        String autologin = request.getParameter("autologin");
        if (autologin != null) {
            System.out.println("用户设置为自动登录...");
            //Cookie为用户登录信息 base64加密用户名_原始密码
            Cookie cookie = new Cookie("loginInfo", Base64.encode(user.getUsername()) + "_" + user.getPassword());
            cookie.setMaxAge(10 * 24 * 60 * 60);//单位s
            cookie.setPath(request.getContextPath());//创建cookie时默认path为当前servlet的上级目录
            response.addCookie(cookie);
        }
        
        HttpSession session = request.getSession();
        session.setAttribute("user", loginUser);
        response.getWriter().write("登录成功,跳转中...");
        response.setHeader("refresh", "1,url=" + request.getContextPath() + "/main.jsp");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
5. 过滤器高级设置
    <filter>
        <filter-name>HighConfigFilter</filter-name>
        <filter-class>com.gaoshiyi.web.filter.HighConfigFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HighConfigFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher><!-- 针对直接访问的资源进行过滤 -->
        <dispatcher>FORWARD</dispatcher><!-- 针对间接动态包含的资源进行过滤 -->
        <dispatcher>INCLUDE</dispatcher><!-- 针对间接转发的资源进行过滤 -->
    </filter-mapping>

小知识:
Base64编码原理:
将3字节(24位)-->4字节(32位):取每个字节的前6位最高位补00
1001 1010 0011 1100 1011 1110
0010010 00100011 00110010 00111110 每个字节的取值范围00000000~00111111(0-63共64个整数)
Base64是一个码表
Base64编码会把3字节的二进制数据编码为4字节的文本数据,长度增加33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用\x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。

Base64码表

base64码表
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,375评论 6 343
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 3,731评论 0 11
  • 长街灯影随风动,斜飞细雨黄花重。举酒笑相迎,青樽动客情。 一别亲故远,万里独归雁。身似水中禽,诗如地上尘。
    莫愁Jessie阅读 339评论 5 12