过滤器要做的事情:

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

响应过滤器:

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



过滤器和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. cs229_part2

    part2 这节课主要讲的是生成式模型,那么与这个生成式模型相对于的就是我们上节课所讲那几个辨别式模型.所以生成式模型和辨别式模型的区别是什么呢.我先给出数学上的定义: 这是我们上节课线性回归所用的给 ...

  2. python基础学习笔记——模块

    自定义模块 我们今天来学习一下自定义模块(也就是私人订制),我们要自定义模块,首先就要知道什么是模块啊 一个函数封装一个功能,比如现在有一个软件,不可能将所有程序都写入一个文件,所以咱们应该分文件,组 ...

  3. HDU1007 TLE代码和AC代码对比

    这题卡了一天,上午开始看算法导论,然后实现了,一开始是wa,后来TLE,由于我开始的实现方式比较笨,而且在递归调用的时候很是混乱,用了好多数组.导致我的代码不断的出问题.具体是算法导论33-4. 后来 ...

  4. 转载:CreateMutex WaitForSingleObject ReleaseMutex使用

    HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes,// BOOL bInitialOwner,  // flag for init ...

  5. poj 1061 青蛙的约会(二元一次不定方程)

      Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要 ...

  6. 将RabbitMq用好需要了解的一些基础知识

    本文面向有一定RabbitMq基础的童鞋. 首先,我们来理理RabbitMq的一些基本概念: Connection: 客户端与RabbitMq服务器节点的Tcp链接. Channel: 信道,因为一条 ...

  7. 【HDOJ6222】Heron and His Triangle(Java,二分,递推)

    题意:让你找这样的一个三角形,三条边为t,t-1,t+1,并且面积为整数,最后满足t大于等于n. n<=1e30 思路:直接推式子不会,打表找规律 f(n)=4*f(n-1)-f(n-2)(n& ...

  8. CSV文件导出2

    public void exportCSVFile( HttpServletResponse response, ResultSet rs,String fileName,String headers ...

  9. Redis数据结构之字典

    Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对. 一.字典结构定义1. 哈希表节点结构定义: 2. 哈希表结构定义: 3. 字典 ...

  10. webstorm(二):拼写warning

    逼死强迫症之对拼写进行检查,警告 typo:in word “msgfromfather”