过滤器要做的事情:
请求过滤器:完毕安全检查,又一次格式化请求首部或体。建立请求审计或日志
响应过滤器:
    压缩响应流,追加或改动响应流创建一个全然不同的响应.

过滤器和servlet三个相似地方:
1.容器知道过滤器的api,过滤器api的其他成员能够訪问ServletContext 还能够与其他过滤器链接
2.容器管理过滤器的生命周期,过滤器有init和destroy方法。还有doFilter方法
3.web应用能够有非常多过滤器。须要在配置文件里配置

过滤器的生命周期
init 容器实例化一个过滤器时。在init方法中完毕调用过滤器之前全部的初始化任务。

保存filterConfig对象
的一个引用,以备过滤去以后使用.
其次调用 doFIlter 能够保存username记录到一个文件里,压缩响应输出。

最后destroy删除一个过滤器实例,

FilterChain的doFIlter 方法要负责明白接下来调用谁的doFilter放大,假设到达链尾,则要确定调用哪个servlet的service方法。

在配置文件里确定过滤器的顺序
在配置文件里做三件事
1.声明过滤器
2.将过滤器映射到你想过滤的web资源
3,组织这些映射,创建过滤器调用序列
声明过滤器
<filter>
      <filter-name>BeerRequest</filter-name>
      <filter-class>com.gac.test.BeerRequestFilter</filter-class>
      <init-param>
          <param-name>LogFileName</param-name>
          <param-value>UserLog.txt</param-value>
      </init-param>
  </filter>
  声明url模式的过滤器映射
  <filter-mapping>
      <filter-name>BeerRequest</filter-name>
      <url-pattern>*.do</url-pattern>
  </filter-mapping>
声明相应servlet名的过滤器映射
 <filter-mapping>
      <filter-name>BeerRequest</filter-name>
      <servlet-name>AdviceServlet</servlet-name>
  </filter-mapping>

为通过请求分派请求的web资源声明一个过滤器映射
 <filter-mapping>
      <filter-name>MonitorFilter</filter-name>
      <url-pattern>*.do</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    和/或
    <dispatcher>INCLUDE</dispatcher>
    和/或
    <dispatcher>FORWARD</dispatcher>
    和/或
    <dispatcher>ERRO</dispatcher>
  </filter-mapping>
声明规则:
必需要有filter-name
必需要有url-pattern或servlet-name元素当中之中的一个
能够有0-4个dispatcher
Request值表示对client请求启用过滤器,假设没有指定<dispatcher>元素。则默觉得
Rquest

INCLUDE值表示对由一个include()调用分派来的请求启用过滤器
FORWARD值表示对一个由forward()调用分派来的请求启用过滤器
ERROR值表示对错误处理调用资源启用过滤器

过滤器请求路径样例
<filter-mapping>
    <filter-name>Filter1</filter-name>                           
    <url-pattern>/Recipes/*<url-pattern>       /Recipes/HopsReport.do 过滤器序列 1 5

</filter-mapping>                  /Recipes/HopsList.do 过滤器 15 2                                    
<filter-mapping>                                            
    <filter-name>Filter2</filter-name>          /Recipes/Modify/ModRecipes.do 过滤器 1 5 4
    <url-pattern>/Recipes/HopsList.do<url-pattern>  /HopsList.do 过滤器 5
</filter-mapping>
<filter-mapping>                                         /Recipes/Add/AddRecipes.do 过滤器 1 3 5
    <filter-name>Filter3</filter-name>
    <url-pattern>/Recipes/Add/*<url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>Filter4</filter-name>
    <url-pattern>/Recipes/Modify/ModRecipes.do<url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>Filter5</filter-name>
    <url-pattern>/*<url-pattern>

</filter-mapping>

/**************************************************************/

//过滤器必须实现Filter接口
public class BeerRequestFilter implements Filter{

private FilterConfig fc;
    //完毕清理工作
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        
    }

//详细的业务逻辑
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletRequest httpReq = (HttpServletRequest) req;//能够将请求和响应对象强制转换为Http类型
        String name = httpReq.getRemoteUser();
        if(name != null){
            fc.getServletContext().log("User"+name +"is updating");
        }
        chain.doFilter(req, resp);//接下来要调用的过滤器或者servlet
        
    }

//必须实现init 通常只在当中保存配置config对象
    @Override
    public void init(FilterConfig config) throws ServletException {
        // TODO Auto-generated method stub
        this.fc = config;
    }

}

/***************************************************************/

为过滤器压缩数据响应为了不实现太多的函数降低复杂性能够利用包装器。
利用包装器的演示样例
public class CompressFilter implements Filter{

private ServletContext ctx;
    private FilterConfig cfg;
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        cfg = null;
        ctx = null;
    }

//这个过滤器核心是用装饰包装响应对象,他用一个压缩的IO流包装输出流.
    //当且仅当客户包括一个Accept-Encoding首部 才会完毕输出流压缩
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp  =(HttpServletResponse) response;
        
        String valid_encodings = req.getHeader("Accept-Encoding");//客户是否接收gzip压缩
        if( valid_encodings.indexOf("gzip") > -1 ){
            ComPressResponseWrapper wrappedResp = new ComPressResponseWrapper(resp);
            wrappedResp.setHeader("Content-Encoding","gzip");
            chain.doFilter(req, wrappedResp);
            
            GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream();
            gzos.finish();
            ctx.log(cfg.getFilterName()+": finished the request. ");
            
        }else{
            ctx.log(cfg.getFilterName()+": no encoding performed.");
        }
    }

//init方法保存配置对象,并保存servlet上下文对象的一个直接引用 以便完毕日志记录
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        this.cfg = filterConfig;
        ctx = cfg.getServletContext();
        ctx.log(cfg.getFilterName()+" initialized.");
    }

}

public class ComPressResponseWrapper extends HttpServletResponseWrapper{

private GZIPServletOutputStream servletGzipOS = null;//servlet响应的压缩输出流
    private PrintWriter pw = null;
    
    public ComPressResponseWrapper(HttpServletResponse response) {
        super(response);
        // TODO Auto-generated constructor stub
    }
    
    public void setContentLength(int len){}
    
    /*过滤器使用这个装饰器的方法压缩过滤器提供一个GZIP输出流的句柄,以便过滤器完毕和刷新输出GZIP流*/
    public GZIPOutputStream getGZIPOutputStream(){
        return this.servletGzipOS.internalGzipOS;
        
    }
    
    private Object streamUsed = null;//同意訪问所装饰的servlet输出流
    public ServletOutputStream getOutputStream()throws IOException{
        //仅当servlet还没有訪问打印书写器时 同意servlet訪问servlet输出流
            if((null != streamUsed) && (streamUsed!=pw)){
                throw new IllegalStateException();
            }
            
            //用我们的压缩输出流包装原来的servlet输出流
            if(servletGzipOS == null){
                servletGzipOS =
                        new GZIPServletOutputStream(getResponse().getOutputStream());
                
                streamUsed = servletGzipOS;
            }
            return servletGzipOS;
    }
    
    //执行訪问所装饰的打印书写器
    public PrintWriter getWriter() throws IOException{
        if((streamUsed != null) && (streamUsed != servletGzipOS)){
            throw new IllegalStateException();
        }
        if(pw == null){
            servletGzipOS =
                    new GZIPServletOutputStream(getResponse().getOutputStream());
            OutputStreamWriter osw =
                    new OutputStreamWriter(servletGzipOS,getResponse().getCharacterEncoding());
            pw = new PrintWriter(osw);
            streamUsed = pw;
        }
        return pw;
    }

}
class GZIPServletOutputStream extends ServletOutputStream{

/*internalGzipOs保存对原始Gzip流的一个引用。这个实例变量在包范围内私有,所以响应包装器能够訪问这个变量*/
    GZIPOutputStream internalGzipOS;
    //装饰器构造函数
    GZIPServletOutputStream(ServletOutputStream sos) throws IOException{
        this.internalGzipOS = new GZIPOutputStream(sos);
    }
    //这种方法把write调用托付给GZIP压缩流 从而实现压缩装饰 GZIP压缩流包装了原来的ServletOutputStream
    @Override
    public void write(int b) throws IOException {
        // TODO Auto-generated method stub
        internalGzipOS.write(b);
    }

}

转载于:https://www.cnblogs.com/clnchanpin/p/6852725.html

javaweb 中的过滤器 包装器相关推荐

  1. java脏字过滤_分享JavaWeb中filter过滤器的案例妙用 - 脏话过滤/编码过滤/代码过滤...

    案例1. 利用Servlet的过滤器Filter进行完成脏话过滤 package cn.javabs.filter; import java.io.IOException; import javax. ...

  2. java脏话模糊对比_分享JavaWeb中filter过滤器的案例妙用 - 脏话过滤/编码过滤/代码过滤...

    案例1. 利用Servlet的过滤器Filter进行完成脏话过滤 package cn.javabs.filter; import java.io.IOException; import javax. ...

  3. 【JavaEE进阶系列 | 从小白到工程师】JavaWeb中的过滤器(Filter)和监听器(Listener)区别,看这一篇就够

    文章目录

  4. java类包装器有什么用_Java中的包装器类

    java类包装器有什么用 Wrapper class in java are the Object representation of eight primitive types in java. A ...

  5. Java包装器类及自动装箱(自动打包)

    1.为什么需要包装器类? Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便.例如,我们有时候需要将int这种基本类型转换为对象类型的,所有的 ...

  6. Python -- 抽象类、包装器

    关键字:抽象类.包装器 Python 没有从语言层面支持抽象类概念 我们可以通过abc模块来制造抽象类的效果 在定义类的时候通过指定metaclass=ABCMeta可以将类声明为抽象类 抽象类是不能 ...

  7. JavaWeb项目中如何扩展一个Request对象——包装器HttpServletRequestWrapper

    一.使用场景 在一个JavaWeb中我们会遇到统一处理出入参或者处理特殊参数的场景,这些场景就需要我们扩展我们的Request对象.所谓的包装器就是在原来的基础上包装一下就是在原来功能上添加一些其他功 ...

  8. JavaWeb中监听器Listener+过滤器filter+拦截器interceptor区别

    JavaWeb中监听器Listener+过滤器filter+拦截器interceptor区别 如果从整个项目中看,一个servlet请求的执行过程就变成了这样context-param–>lis ...

  9. java ssh过滤器_SSH中的过滤器,拦截器,监听器的一些基本认识

    今天被一个朋友问起在SSH的项目中,过滤器.拦截器.监听器都分别是什么,又都是干什么用的.结合目前学习到的和自己应用的体会,大概有以下几个方面. 1.过滤器:顾名思义就是过滤请求内容的,所谓的过滤就是 ...

最新文章

  1. php读取西门子plc_简单说一些PLC中模拟量的相关概念
  2. 平衡正则 html,正则表达式-利用平衡组匹配html
  3. 买卖股票的最佳时机—leetcode121
  4. python的基本原理_Python函数基本使用原理详解
  5. mailcore -- POP
  6. 安全问题汇总(一) 证书定期检查和及时更新
  7. jQuery源码阅读(一)---jQuery源码整体架构
  8. 商品id- item_id /条形码/skuid
  9. HBuilder表单提交php出现内部服务器错误
  10. 深圳APP开发婚恋社交App
  11. 拉美外贸收款:BBVA银行
  12. 2018“回响中国”腾讯教育年度总评榜 vipJr、TutorABC上榜
  13. 蓝桥杯-基础练习 查找整数
  14. js脚本实现自动签到功能
  15. demo代码目录整理
  16. 过分了,这些算法妹子们肝了一本1200页的AI全栈技术手册
  17. 深圳大学计算机网络实验报告,深圳大学陆楠第一次计算机网络作业.doc
  18. 2058(等差求和)
  19. 最近帮别人改论文格式心得体会一:如何让页眉或者页脚或者页码不一样
  20. springboot系列文章之使用单元测试

热门文章

  1. (2 sat) hdu 1824
  2. 学习 .net 的一些主要网站
  3. ASP.NET DataSet查询结果转换为JSON格式数据
  4. LA3644简单并查集判环
  5. 【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 使用 @Category 注解进行方法注入 | 分类注入方法查找优先级 )
  6. 【Groovy】MOP 元对象协议与元编程 ( 通过 MetaMethod#invoke 执行 Groovy 方法 )
  7. 【Groovy】集合遍历 ( 使用 for 循环遍历集合 | 使用集合的 each 方法遍历集合 | 集合的 each 方法返回值分析 )
  8. 【C 语言】字符串模型 ( 字符串翻转模型 | 借助 递归函数操作 逆序字符串操作 | strncat 函数 )
  9. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 后续分析 | Application 替换位置 )
  10. 【软件工程】CMMI 能力成熟度模型集成 ( CMMI 过程管理过程域 | CMMI 项目管理过程域 ) ★