[Servlet&JSP] 封装器的使用

过滤器可以在执行Servlet的service()方法前后,进行前置和后置处理。但是有些信息无法更改,例如请求参数。使用请求封装器及相应封装器,将容器产生的请求与相应对象加以封装,可以针对某个请求信息或响应进行加工处理。

请求封装器

HttpServletRequestWrapper实现了HttpServletRequest接口,以下范例通过继承HttpServletRequestWrapper实现了一个请求封装器,可以请请求参数中的角括号替换为替代字符。

import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class CharacterRequestWrapper extends HttpServletRequestWrapper{
    private Map<String, String> escapeMap;

    public CharacterRequestWrapper(HttpServletRequest request,
            Map<String, String> escapeMap) {
        super(request); //封装传入的请求对象
        this.escapeMap = escapeMap;
    }

    @Override
    public String getParameter(String name) { //重写getParameter()方法
        return doEscape(this.getRequest().getParameter(name));
    }

    private String doEscape(String parameter) {
        if (parameter == null) {
            return null;
        }
        String result = parameter;
        Iterator<String> it = escapeMap.keySet().iterator();
        while(it.hasNext()) {
            String origin = it.next();
            String escape = escapeMap.get(origin);
            result = result.replaceAll(origin, escape);
        }

        return result;
    }
}

可以使用这个请求封装器搭配过滤器,以进行字符过滤的服务。例如:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

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;

public class CharacterFilter implements Filter {
    private Map<String, String> escapeMap;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        BufferedReader reader = null;
        try {
            String escapeListFile = filterConfig.getInitParameter("ESCAPE_LIST");
            reader = new BufferedReader(new InputStreamReader(
                    filterConfig.getServletContext().getResourceAsStream(escapeListFile)));

            String input = null;
            escapeMap = new HashMap<String, String>();
            while ((input = reader.readLine()) != null) {
                String[] token = input.split("\t");
                escapeMap.put(token[0], token[1]);
            }
        } catch (IOException ex) {
            Logger.getLogger(CharacterFilter.class.getName())
                    .log(Level.SEVERE, null, ex);
        } finally {
            try {
                reader.close();
            } catch (IOException ex) {
                Logger.getLogger(CharacterFilter.class.getName())
                        .log(Level.SEVERE, null, ex);
            }
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        //将原请求对象封装到CharacterRequestWrapper中
        HttpServletRequest requestWrapper =
                new CharacterRequestWrapper((HttpServletRequest)request, escapeMap);
        //将CharacterRequestWrapper对象当做请求参数传入doFilter()
        chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}

响应封装器

如果想要对响应的内容进行压缩处理等,可以在响应封装器部分继承HttpServletResponseWrapper类来对HttpServletResponse对象进行封装。

如要对浏览器进行输出响应,必须通过getWriter()取得PrintWriter,或是通过getOutputStream()取得ServletOutputStream。所以针对压缩输出的请求,主要就是继承HttpServletResponseWrapper之后,通过重写这两个方法来达成的。

在这里压缩功能将采用GZIP格式,这是浏览器可以接受的压缩格式,可以使用GZIPOutputStream类来实现。由于getWriter()的PrintWriter在创建时也是必须要用到ServletOutputStream,所以这里首先扩展ServletOutputStream类,让它具有压缩功能。

GzipServletOutputStream.java:

package club.chuxing;

import java.io.IOException;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;

public class GZipServletOutputStream extends ServletOutputStream{
    private GZIPOutputStream gzipOutputStream;

    public GZipServletOutputStream(ServletOutputStream servletOutputStream)
            throws IOException {
        this.gzipOutputStream = new GZIPOutputStream(servletOutputStream);
    }

    public void write(int b) throws IOException {
        //输出时通过GZIPOutputSteam的write()压缩输出
        gzipOutputStream.write(b);
    }

    public GZIPOutputStream getGzipOutputStream() {
        return gzipOutputStream;
    }

    @Override
    public boolean isReady() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void setWriteListener(WriteListener listener) {
        // TODO Auto-generated method stub
    }
}

CompressionResponseWrapper.java:

package club.chuxing;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class CompressionResponseWrapper extends HttpServletResponseWrapper {
    private GZipServletOutputStream gzServletOutputStream;
    private PrintWriter printWriter;
    public CompressionResponseWrapper(HttpServletResponse resp) {
        super(resp);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if (printWriter != null) {
            throw new IllegalStateException();
        }
        if (gzServletOutputStream == null) {
            gzServletOutputStream = new GZipServletOutputStream(
                    getResponse().getOutputStream());
        }

        return gzServletOutputStream;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        if (gzServletOutputStream != null) {
            throw new IllegalStateException();
        }
        if (printWriter == null) {
            gzServletOutputStream = new GZipServletOutputStream(
                    getResponse().getOutputStream());
            OutputStreamWriter osw = new OutputStreamWriter(
                    gzServletOutputStream, getResponse().getCharacterEncoding());
            printWriter = new PrintWriter(osw);
        }

        return printWriter;
    }

    @Override
    public void setContentLength(int len) {

    }

    public GZIPOutputStream getGZIPOutputStream() {
        if (this.gzServletOutputStream == null) {
            return null;
        }
        return this.gzServletOutputStream.getGzipOutputStream();
    }
}

CompressionFilter.java(压缩过滤器):

package club.chuxing;

import java.io.IOException;
import java.util.zip.GZIPOutputStream;

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 CompressionFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse res = (HttpServletResponse)response;

        String encodings = req.getHeader("accept-encoding");
        if ((encodings != null) && encodings.indexOf("gzip") > -1) {
            //建立响应封装
            CompressionResponseWrapper responseWrapper =
                    new CompressionResponseWrapper(res);
            //设置响应内容编码为gzip格式
            responseWrapper.setHeader("content-encoding", "gzip");

            chain.doFilter(request, responseWrapper);

            GZIPOutputStream gzipOutputStream = responseWrapper.getGZIPOutputStream();
            if (gzipOutputStream != null) {
                //调用GZIPOutputStream的finish()方法完成压缩输出
                gzipOutputStream.finish();
            }
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}

最后,将过滤器设置在web.xml中,响应就会是压缩过后的内容。

时间: 2024-12-31 02:04:39

[Servlet&amp;JSP] 封装器的使用的相关文章

调优servlet和JSP的程序性能

本文讲述了调整JSP和servlet的一些非常实用的方法,它可使你的servlet和JSP页面响应更快,扩展性更强.而且在用户数增加的情况下,系统负载会呈现出平滑上长的趋势.在本文中,我将通过一些实际例子和配置方法使得你的应用程序的性能有出人意料的提升.其中,某些调优技术是在你的编程工作中实现的.而另一些技术是与应用服务器的配置相关的.在本文中,我们将详细地描述怎样通过调整servlet和JSP页面,来提高你的应用程序的总体性能.在阅读本文之前,假设你有基本的servlet和JSP的知识. 方法

用servlet将jsp文件内容转为html

用servlet将jsp文件内容转为html. 用servlet将jsp文件内容转为html.代码如下: package examples; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import javax.serv

Servlet、Jsp性能优化

js|servlet|性能|优化 你的J2EE应用是不是运行的很慢?它们能不能承受住不断上升的访问量?本文讲述了开发高性能.高弹性的JSP页面和Servlet的性能优化技术.其意思是建立尽可能快的并能适应数量增长的用户及其请求.在本文中,我将带领你学习已经实践和得到证实的性能调整技术,它将大大地提高你的servlet和jsp页面的性能,进而提升J2EE的性能.这些技术的部分用于开发阶段,例如,设计和编码阶段.另一部分技术则与配置相关. 技术1:在HttpServlet init()方法中缓存数据

一、Servlet和JSP概述

js|servlet  1.1 Java Servlet及其特点 Servlet是Java技术对CGI编程的回答.Servlet程序在服务器端运行,动态地生成Web页面.与传统的CGI和许多其他类似CGI的技术相比,Java Servlet具有更高的效率,更容易使用,功能更强大,具有更好的可移植性,更节省投资(更重要的是, Servlet程序员收入要比Perl程序员高:-):     高效      在传统的CGI中,每个请求都要启动一个新的进程,如果CGI程序本身的执行时间较短,启动进程所需要

Servlet和JSP迈上新台阶

js|servlet 即将面世的J2EE 1.4提供用Java开发Web应用程序的新的Servlet 2.4和JavaServer Pages (JSP) 2.0技术.本文展示了这两种技术的新特性,并在适当的地方提供每个特性的示例代码.本文假设读者熟悉以前的 Servlet 2.3和JSP 1.2版本.给出的例子已用Tomcat 5(包含在Java Web Services Developer Pack 1.2中)进行了测试. Servlet和JSP毫无疑问是两种应用最广的J2EE技术.Serv

Java Servlet 和 JSP教程(2)

js|servlet|教程 2 安装 2.1 安装Servlet和JSP开发工具 要学习Servlet和JSP开发,首先你必须准备一个符合Java Servlet 2.1/2.2和JavaServer Pages1.0/1.1规范的开发环境.Sun提供免费的JavaServer Web Development Kit(JSWDK),可以从http://java.sun.com/products/servlet/下载. 安装好JSWDK之后,你还要告诉javac,在编译文件的时候到哪里去寻找Ser

Java Servlet 和 JSP教程(3)

js|servlet|教程 3 Servlet 3.1 Servlet基本结构 下面的代码显示了一个简单Servlet的基本结构.该Servlet处理的是GET请求,所谓的GET请求,如果你不熟悉HTTP,可以把它看成是当用户在浏览器地址栏输入URL.点击Web页面中的链接.提交没有指定METHOD的表单时浏览器所发出的请求.Servlet也可以很方便地处理POST请求.POST请求是提交那些指定了METHOD="POST"的表单时所发出的请求,具体请参见稍后几节的讨论. import

Servlet和JSP 性能调整技术

js|servlet|性能 概述 在本文中, Rahul Chaudhary将描述性能调整技术 (PTT performance-tuning techniques) 的使用,来提升servlets 和JSP 的性能,以此来提升你的J2EE应用的性能.笔者假设读者具有基础的servlets 和JSPs知识. 你的J2EE应用程序运行缓慢么?它们可以满足足够的压力么?本文将会描述如何在开发高性能的应用和JSP以及servlets中使用性能调整技术 (PTT performance-tuning t

关于Servlet、Jsp中的多国语言显示

js|servlet|显示 因为一直不信Java竟会有不能混排显示多国语言的BUG,这个周末研究了一下Servlet.Jsp的多国语言显示的问题,也就是Servlet的多字符集问题,由于我对字符集的概念还不是很清晰所以写出的东西未必是准确的,我是这样理解Java中的字符集的:在运行时,每个字符串对象中存储的都是编码为UNICODE内码的(我觉得所有的语言中都是有相应编码的,因为在计算机内部字符串总是用内码来表示的,只不过一般计算机语言中的字符串编码时平台相关的,而Java则采用了平台无关的UNI