过滤器第二篇【编码、敏感词、压缩、转义过滤器】(二)

简介: 在上篇博文中,我们已经讲解了过滤器的基本概念,使用以及简单的Servlet应用了。这篇博文主要讲解过滤器的高级应用。。

压缩资源过滤器

按照过滤器的执行顺序:执行完目标资源,过滤器后面的代码还会执行。所以,我们在过滤器中可以获取执行完目标资源后的response对象!

我们知道sun公司提供的response对象调用write()方法,是直接把数据返回给浏览器的。我们要想实现压缩的功能,write()方法就不能直接把数据写到浏览器上!

这和上面是类似的,过滤器传递给目标资源的response对象就需要被我们增强,使得目标资源调用writer()方法的时候不把数据直接写到浏览器上

增强response对象

response对象可能会使用PrintWriter或者ServletOutputStream对象来调用writer()方法的,所以我们增强response对象的时候,需要把getOutputSteam和getWriter()重写

  class MyResponse extends HttpServletResponseWrapper{
        HttpServletResponse response;
        public MyResponse(HttpServletResponse response) {
            super(response);
            this.response = response;
        }
        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            return super.getOutputStream();
        }
        @Override
        public PrintWriter getWriter() throws IOException {
            return super.getWriter();
        }
    }

接下来,ServletOutputSteam要调用writer()方法,使得它不会把数据写到浏览器上。这又要我们增强一遍了!

增强ServletOutputSteam

    /*增强ServletOutputSteam,让writer方法不把数据直接返回给浏览器*/
    class MyServletOutputStream extends ServletOutputStream{
        private ByteArrayOutputStream byteArrayOutputStream;
        public MyServletOutputStream(ByteArrayOutputStream byteArrayOutputStream) {
            this.byteArrayOutputStream = byteArrayOutputStream;
        }
        //当调用write()方法的时候,其实是把数据写byteArrayOutputSteam上
        @Override
        public void write(int b) throws IOException {
            this.byteArrayOutputStream.write(b);
        }
    }

增强PrintWriter

PrintWriter对象就好办了,它本来就是一个包装类,看它的构造方法,我们直接可以把ByteArrayOutputSteam传递给PrintWriter上。59.jpg

 @Override
    public PrintWriter getWriter() throws IOException {
        printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, this.response.getCharacterEncoding()));
        return printWriter;
    }

获取缓存数据

我们把数据都写在了ByteArrayOutputSteam上了,应该提供方法给外界过去缓存中的数据!

 public byte[] getBuffer() {
        try {
            //防止数据在缓存中,要刷新一下!
            if (printWriter != null) {
                printWriter.close();
            }
            if (byteArrayOutputStream != null) {
                byteArrayOutputStream.flush();
                return byteArrayOutputStream.toByteArray();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

增强response的完整代码

class MyResponse extends HttpServletResponseWrapper{
    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    private PrintWriter printWriter ;
    private HttpServletResponse response;
    public MyResponse(HttpServletResponse response) {
        super(response);
        this.response = response;
    }
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        //这个的ServletOutputSteam对象调用write()方法的时候,把数据是写在byteArrayOutputSteam上的
        return new MyServletOutputStream(byteArrayOutputStream);
    }
    @Override
    public PrintWriter getWriter() throws IOException {
        printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, this.response.getCharacterEncoding()));
        return printWriter;
    }
    public byte[] getBuffer() {
        try {
            //防止数据在缓存中,要刷新一下!
            if (printWriter != null) {
                printWriter.close();
            }
            if (byteArrayOutputStream != null) {
                byteArrayOutputStream.flush();
                return byteArrayOutputStream.toByteArray();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

过滤器

 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        MyResponse myResponse = new MyResponse(response);
        //把被增强的response对象传递进去,目标资源调用write()方法的时候就不会直接把数据写在浏览器上了
        chain.doFilter(request, myResponse);
        //得到目标资源想要返回给浏览器的数据
        byte[] bytes = myResponse.getBuffer();
        //输出原来的大小
        System.out.println("压缩前:"+bytes.length);
        //使用GZIP来压缩资源,再返回给浏览器
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
        gzipOutputStream.write(bytes);
        //得到压缩后的数据
        byte[] gzip = byteArrayOutputStream.toByteArray();
        System.out.println("压缩后:" + gzip.length);
        //还要设置头,告诉浏览器,这是压缩数据!
        response.setHeader("content-encoding", "gzip");
        response.setContentLength(gzip.length);
        response.getOutputStream().write(gzip);
    }

测试

  • 在Servlet上输出一大段文字:
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("fdshfidsuhfidusfhuidsfhuidshdsuifhsd" +
                "uifhsduifffffdshfidsuhfidusfhuidsfhuidshdsuif" +
                "hsduifhsduifffffdshfidsuhfidusfhuidsfhuidshd" +
                "suifhsduifhsduifffffdshfidsuhfidusfhuidsfhuidsh" +
                "dsuifhsduifhsduifffffdshfidsuhfidusfhuidsfhuids" +
                "hdsuifhsduifhsduifffffdshfidsuhfidusfhuidsfhuid" +
                "shdsuifhsduifhsduiffdshfidsuhfidusfhuidsfhuids" +
                "hdsuifhsduifhsduifffffdshfidsuhfidusfhuidsfhui" +
                "dshdsuifhsduifhsduifffffdshfidsuhfidusfhuidsfh" +
                "uidshdsuifhsduifhsduifffffdshfidsuhfidusfhuids" +
                "fhuidshdsuifhsduifhsduifffffdshfidsuhfidusfhuid" +
                "sfhuidshdsuifhsduifhsduifffffdshfidsuhfidusfhui" +
                "dsfhuidshdsuifhsduifhsduifffffdshfidsuhfidusfh" +
                "uidsfhuidshdsuifhsduifhsduifffffdshfidsuhfidusf" +
                "huidsfhuidshdsuifhsduifhsduifffffdshfidsuhfidus" +
                "fhuidsfhuidshdsuifhsduifhsduifffffdshfidsuhfid" +
                "usfhuidsfhuidshdsuifhsduifhsduifffffdshfidsuhf" +
                "idusfhuidsfhuidshdsuifhsduifhsd" +
                "uifffffdshfidsuhfidusfhuidsfhuidshdsuifhsduifhsduifffffff");
    }

效果:

60.jpg

HTML转义过滤器

只要把getParameter()获取得到的数据转义一遍,就可以完成功能了。

增强request

class MyHtmlRequest extends HttpServletRequestWrapper{
    private HttpServletRequest request;
    public MyHtmlRequest(HttpServletRequest request) {
        super(request);
        this.request = request;
    }
    @Override
    public String getParameter(String name) {
        String value = this.request.getParameter(name);
        return this.Filter(value);
    }
    public String Filter(String message) {
        if (message == null)
            return (null);
        char content[] = new char[message.length()];
        message.getChars(0, message.length(), content, 0);
        StringBuffer result = new StringBuffer(content.length + 50);
        for (int i = 0; i < content.length; i++) {
            switch (content[i]) {
                case '<':
                    result.append("&lt;");
                    break;
                case '>':
                    result.append("&gt;");
                    break;
                case '&':
                    result.append("&amp;");
                    break;
                case '"':
                    result.append("&quot;");
                    break;
                default:
                    result.append(content[i]);
            }
        }
        return (result.toString());
    }
}


目录
相关文章
|
7月前
|
安全 Java 数据安全/隐私保护
数组越界可能导致哪些安全问题?
数组越界可能导致哪些安全问题?
316 57
|
12月前
|
搜索推荐 数据挖掘 数据处理
NVIDIA Triton系列12-模型与调度器2
本文介绍了NVIDIA Triton服务器的“集成推理”功能,涵盖“集成模型”与“集成调度器”两部分,通过示例说明了如何构建一个包含图像预处理、分类和语义分割的推理流水线,强调了模型间数据张量的连接与处理,以及配置集成模型和调度器的具体步骤。
215 1
NVIDIA Triton系列12-模型与调度器2
|
12月前
|
数据采集 人工智能 监控
揭秘数据治理:七步工作法&十大准则全解析
数据治理的“七步工作法”与“十大准则”为企业构建科学、系统、高效的数据治理体系提供了重要的指导和借鉴。企业应结合自身实际情况,灵活运用这些方法和准则,充分挖掘数据潜能,赋能业务创新,实现数字化转型的稳健推进。
1073 0
|
供应链 监控 数据安全/隐私保护
ERP系统中的供应链风险管理与应对策略解析
【7月更文挑战第25天】 ERP系统中的供应链风险管理与应对策略解析
1045 0
|
Shell
|
人工智能 数据可视化 定位技术
【工具使用】QGIS导入csv文件进行数据可视化
【工具使用】QGIS导入csv文件进行数据可视化
783 0
|
SQL Web App开发 缓存
官宣|Apache Flink 1.16 发布公告
Flink 社区正一步一步推动 Streaming warehouse 从概念变为现实并走向成熟。
官宣|Apache Flink 1.16 发布公告
|
Web App开发 弹性计算 Kubernetes
云原生系列 【基于CCE Kubernetes编排实战】
## 基于CCE Kubernetes编排实战 #### 本实验用于指导学员基于CCE完成Kubernetes实验操作。主要包含Kubernetes控制器Deployment、DaemonSet编排操作。 操作前提:预置环境与登录华为云收起 ①预置环境 实验开始之前,为什么需要先预置实验环境? 注意:开始实验之前请点击手册上方"预置实验环境"按钮。 预置实验环境约等待【1分钟】后预置成功。环境预置成功会生成以分配的华为云账号命名的Vpc、安全组。 (2)登录华为云进入【实验操作桌面】,打开Chrome浏览器,首次可自动登录并进入华为云 控制台页面。 如后续关闭浏览器重新登陆或自动
446 1
Bellhop 海底地形起伏条件下的传播特性
由于水下声信道课程大作业的需要,因此本节专门研究海底地形起伏条件下的声传播特性。
709 0
|
机器学习/深度学习 传感器 算法
基于超声图像散斑统计的各向异性扩散滤波器附matlab代码
基于超声图像散斑统计的各向异性扩散滤波器附matlab代码