装饰者模式之servlet过滤器(Filter)网页压缩

来源:互联网 发布:淘宝介入卖家输了 编辑:程序博客网 时间:2024/05/20 23:34

1.装饰者模式定义

动态地给一个对象添加一些额外的职责。就增加功能来说, 装饰模式相比生成子类更为灵活。                                                                    ------《设计模式之禅》

2.通用类图:

这里写图片描述

类图说明:● Component抽象构件Component是一个接口或者是抽象类, 就是定义我们最核心的对象, 也就是最原始的对象。注意: 在装饰模式中, 必然有一个最基本、 最核心、 最原始的接口或抽象类充当Component抽象构件。 ● ConcreteComponent 具体构件ConcreteComponent是最核心、 最原始、 最基本的接口或抽象类的实现, 你要装饰的就是它。  ● Decorator装饰角色一般是一个抽象类, 做什么用呢? 实现接口或者抽象方法, 它里面可不一定有抽象的方法呀, 在它的属性里必然有一个private变量指向Component抽象构件。 ● 具体装饰角色ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类, 你要把你最核心的、 最原始的、 最基本的东西装饰成其他东西。                                                                    ------《设计模式之禅》  

3.类图代码:

public abstract class Component {//抽象的方法    public abstract void operate();}public class ConcreteComponent extends Component {//具体实现@Override    public void operate() {        System.out.println("do Something");    }}public abstract class Decorator extends Component {    private Component component = null;    //通过构造函数传递被修饰者        public Decorator(Component _component){        this.component = _component;    }    //委托给被修饰者执行    @Override    public void operate() {        this.component.operate();    }}public class ConcreteDecorator1 extends Decorator {//定义被修饰者    public ConcreteDecorator1(Component _component){        super(_component);}    //定义自己的修饰方法    private void method1(){        System.out.println("method1 修饰");    }    //重写父类的Operation方法    public void operate(){        this.method1();        super.operate();    }}

servlet过滤器之网页压缩

应用: 如今租赁的服务器有的是按照流量来节省流量,所以网页压缩技术有助于节省流量,     并且可以提高用户的网的响应速度,大大提高了用户体验。
  • 所用技术:

    • java 的GZIPOutputStream类进行gzip压缩。
    • 通过javaweb的过滤器,对服务端发响应的数据进行压缩。
    • 装饰者模式,对已经存在的方法进行重写。
  • 分析:

    • 运用过滤器,对服务器每一次的响应的数据进行gzip压缩。
    • 在servlet中的response.getwriter().writer()向客户端发送数据,可是中间的数据无法再过滤器中截取。
    • 以上,所以需要重写response中的PrintWriter方法,将响应数据在发送到客户端之前先保存到ServletResponse的成员缓冲区中。
    • 随后在过滤器中将响应内容进行压缩,再发送给客户端。

过滤器代码

public class GIZPFilter implements Filter {    public GIZPFilter() {    }    public void destroy() {    }    public void init(FilterConfig fConfig) throws ServletException {    }    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)     throws IOException, ServletException {        //对响应中的数据先进行编码        req.setCharacterEncoding("utf-8");        //对response进行装饰        HttpServletResponse response = (HttpServletResponse) res;        //进行包装        MyHttpResponse myResponse = new MyHttpResponse(response);        //放行,在servlet向缓冲区中写数据        chain.doFilter(req, myResponse);        //获取缓冲区中的内容        char[] content = myResponse.getBuf().toCharArray();        //创建缓冲区        ByteArrayOutputStream bos = new ByteArrayOutputStream();        //进行压缩        GZIPOutputStream gzip = new GZIPOutputStream(bos);        //向bos2缓冲区中写入数据        gzip.write(new String(content).getBytes());        //刷新缓冲区        gzip.finish();        System.out.println("压缩后的数据大小:" + new String(bos.toByteArray()).length());        System.out.println(new String(content));        //设置响应体中的字体        myResponse.setContentType("text/html;charset=utf-8");        //设置浏览器解析格式        myResponse.setHeader("content-encoding", "gzip");        //向浏览器写数据        myResponse.getOutputStream().write(bos.toByteArray());    }}//重写的类class MyHttpResponse extends HttpServletResponseWrapper {    private HttpServletResponse response = null;    //定义缓冲区    private CharArrayWriter buf = new CharArrayWriter();    public CharArrayWriter getBuf() {        return buf;    }    public MyHttpResponse(HttpServletResponse response) {        super(response);        this.response = response;    }    @Override    public PrintWriter getWriter() throws IOException {        //创建带缓冲区的PrintWriter对象(API中可查)        return new PrintWriter(buf);    }}

服务器代码:

public void doGet(HttpServletRequest request, HttpServletResponse response)     throws  ServletException, IOException {        //准备数据        StringBuffer sb = new StringBuffer();        for(int i=1;i<=3000;i++){            sb.append("abcd你好");        }        System.out.println("压缩前的数据大小: "+sb.toString().getBytes().length);        //这里的response已经是过滤器中定义的MyHttpResponse 类        PrintWriter out = response.getWriter();        out.write(sb.toString());        //关闭并刷新缓冲区        out.close();    }
1 0
原创粉丝点击