过滤器要做的事情:

请求过滤器:完毕安全检查,又一次格式化请求首部或体。建立请求审计或日志

响应过滤器:

    压缩响应流,追加或改动响应流创建一个全然不同的响应.



过滤器和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);

    }



}

javaweb 中的过滤器 包装器的更多相关文章

  1. JavaWeb中监听器+过滤器+拦截器区别、配置和实际应用

    JavaWeb中监听器+过滤器+拦截器区别.配置和实际应用 1.前沿上一篇文章提到在web.xml中各个元素的执行顺序是这样的,context-param-->listener-->fil ...

  2. asp.net core 2.2 中的过滤器/筛选器(上)

    ASP.NET Core中的过滤器/筛选器 通过使用 ASP.NET Core MVC 中的筛选器,可在请求处理管道中的特定阶段之前或之后运行代码. 注意:本主题不适用于 Razor 页面. ASP. ...

  3. MVC中的过滤器/拦截器怎么写

    创建一个AuthenticateFilterAttribute(即过滤器/拦截器) 引用System.Web.Mvc; public class AuthenticateFilterAttribute ...

  4. 【Head First Servlets and JSP】笔记 28: 过滤器与包装器

    1.过滤器的执行顺序: <url-pattern> 为第一梯队, <servlet-name> 为第二梯队,梯队内的执行顺序和 DD 里的声明顺序相同. When the co ...

  5. Java中基本数据类型和包装器类型的关系

    在程序设计中经常用到一系列的数据类型,在Java中也一样包含八中数据类型,这八种数据类型又各自对应一种包装器类型.如下表: 基本类型 包装器类型 boolean Boolean char Charac ...

  6. springboot中使用过滤器、拦截器、监听器

    监听器:listener是servlet规范中定义的一种特殊类.用于监听servletContext.HttpSession和servletRequest等域对象的创建和销毁事件.监听域对象的属性发生 ...

  7. SwiftUI 中一些和响应式状态有关的属性包装器的用途

    SwiftUI 借鉴了 React 等 UI 框架的概念,通过 state 的变化,对 View 进行响应式的渲染.主要通过 @State, @StateObject, @ObservedObject ...

  8. JavaWeb chapter 8 过滤器

    1.  一个中间组件,用于拦截源数据和目的数据之间的消息,过滤二者之间传递的数据: 2.  Servlet过滤器是驻留在Web服务器上的Web组件,过滤从客户端传递到服务器端的请求和相应. 3.  多 ...

  9. JavaWeb之Filter过滤器

    原本计划这一篇来总结JSP,由于JSP的内容比较多,又想着晚上跑跑步减减肥,所以今天先介绍Filter以及它的使用举例,这样的话还有些时间可以锻炼锻炼.言归正传,过滤器从字面理解她的话有拦网.过滤的功 ...

随机推荐

  1. 【php】 布尔值判断

    当转换为 boolean 时,以下值被认为是 FALSE: 布尔值 FALSE 本身 整型值 0(零) 浮点型值 0.0(零) 空字符串,以及字符串 "0" 不包括任何元素的数组 ...

  2. Python9-函数-day9

    初识函数定义与调用 def my_len(): i = 0 for k in s1: i +=1 return i #返回值 # s = 'tim' s1 = '班主任阿娇' length =my_l ...

  3. (原)剑指offer变态跳台阶

    变态跳台阶 时间限制:1秒空间限制:32768K 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法.   分析一下明天是个斐波那契 ...

  4. initcall机制

    参考:initcall机制 /* include/linux/init.h: */ /* For assembly routines */ #define __HEAD .section " ...

  5. 组队赛Day1第一场 GYM 101350 F. Monkeying Around(线段树)

    [题目大意] 有n只猴子坐在树上,m个笑话. 给出每个讲这个笑话的猴子的编号,笑话的编号,和笑话的影响半径. 如果一个树上的猴子听了没听过的笑话,会掉到树下.如果听过并且在树下,就会爬到树上. 问最后 ...

  6. Apache 流框架 Flink,Spark Streaming,Storm对比分析(1)

    此文已由作者岳猛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.Flink架构及特性分析 Flink是个相当早的项目,开始于2008年,但只在最近才得到注意.Flink是 ...

  7. c#笔记2018-12-26

    using System; /*C#学习笔记2018-12-26 * 1.@逐字字符串 * 2.数据类型转换 * 3.变量声明和占位符使用 * 4.接收用户输入值 * 5.const 关键字 * 6. ...

  8. 第五部分 linux系统管理员 开机流程 模组管理 与loader

    第五部分   linux系统管理员  开机流程  模组管理  与loader   开机流程分析 cmos保存电脑硬件的参数 bios 基本的输入输出系统  读取硬件的软件 MBR  master bo ...

  9. vim使用技巧二 模式

    第一部分模式 第2章  普通模式 打开vim的默认状态即为普通模式   普通模式的命令强大  很大程度源于可以把操作符与动作命令结合在一起 技巧7 停顿时请移开画笔   工欲善其事,必先利其器   准 ...

  10. pytorch中torch.unsqueeze()函数与np.expand_dims()

    numpy.expand_dims(a, axis) Expand the shape of an array. Insert a new axis that will appear at the a ...