欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

[Servlet&JSP] 封装器的使用

程序员文章站 2022-05-03 12:40:44
过滤器可以在执行servlet的service()方法前后,进行前置和后置处理。但是有些信息无法更改,例如请求参数。使用请求封装器及相应封装器,将容器产生的请求与相应对象加以封装,可以针对某个请求信...

过滤器可以在执行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 escapemap;

    public characterrequestwrapper(httpservletrequest request, 
            map 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 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 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();
            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中,响应就会是压缩过后的内容。