岁月联盟 · 中国技术网 本站主页 | 安全认证 | 用户服务 | 技术论坛
新闻快报 | 新手学堂 | 黑客特区 | 程序语言 | 数 据 库 | 防 火 墙 | 路由交换 | 系统集成 | 服 务 器 | 存储备份 | 考试认证
Windows | Linux | Java | 协议分析 | 问题解答 | 进程大全 | 网页设计 | 多 媒 体 | 图库资料 | 软件下载 | 站内下载
  您现在的位置: 岁月联盟 >> Java >> J2EE >> Servlet/Jsp >> Java正文
关于装饰Servlet Request对象简介图
作者:未知 文章来源:本站整理 点击数: 更新时间:2007-7-22 19:32:11

  摘要
  
  装饰模式是Erich Gamma等人所著的《设计模式:可利用面向对象软件的基础》一书中众多模式之一。一般来说,此模式在设计Swing的程序员中比较流行,他们用它来改进软件。今天,即使有许多程序是基于Web应用的,装饰模式仍有用武之地,在J2EE的环境下也有使用的价值。
  
  本文说明了如何将装饰模式应用到servlet request对象上。首先,提出了一个与servlet filter有关的问题,并解释了随之而引入的装饰模式。然后,讨论了如何在servlet环境下使用此模式,并列出了使用此模式的几个比较有名的基于servlet的项目。最后,文章通过实现一个删除空白符的filter例子,演示了装饰模式在servlet中的使用。
  
  简介
  
  Servlet规范中所引入的filter令人心动不已,因为它引入了一个功能强大的拦截模式。Filter是这样一种Java对象,它能在request到达servlet的服务方法之前拦截HttpServletRequest对象,而在服务方法转移控制后又能拦截HttpServletResponse对象。你可以使用filter来实现特定的任务,比如验证用户输入,以及压缩web内容。但你拟富有成效地使用过滤器的念头却被你不能改变HttpServletRequest对象的参数的现实扫了兴,因为java.util.Map所包装的HttpServletRequest对象的参数是不可改变的。这极大地缩减了filter的应用范围。至少在一半的时间里,你希望可以改变准备传送给filter的对象。如果在HttpServletRequest对象到达Struts的action servlet之前,我们可以通过一个filter将用户输入的多余空格去掉,难道不是更美妙吗?这样的话,你就不必等到在Struts的action表单验证方法中才进行这项工作了。
  
  幸运的是,尽管你不能改变不变对象本身,但你却可以通过使用装饰模式来改变其状态。
  
  装饰模式
  
  在继承中,你可以通过继承一个父类并覆盖你希望改变的方法来改变对象状态。然而,如果这个对象是由程序的另一个子模块,例如对象工厂 (这里所说的工厂是工厂模式中的术语,下同。译者注) 或是servlet容器所产生的,继承就无能为力了。
  
  装饰模式可用来增加一个现有对象的功能,或是改变其状态。与其使用继承方式来扩展此类,这个模式将一个对象包装成另外一个对象。图1是装饰模式的UML类图。
  
 

  
图1:装饰模式

  
  在图1中,Component是一个接口,其具体实现是ConcreteComponent。要改变Component的状态,你可以修改ConcreteComponent或是扩展它 (通过继承或实现接口的方式,译者注)。然而,如果ConcreteComponent来自于一个工厂,你却无计可施。你所能做的,就是创建一个同为实现了Component接口的装饰类。在图1中,这个装饰类的角色就由Decorator来扮演,在程序中通常表现为接口或抽象类。Decorator类的一个特性就是,它有一个接收Component对象的构造方法。你将拟装饰的对象传递给这个构造方法。在本例中,这个对象就是从工厂获得的ConcreteComponent对象。通过将此装饰对象传递给Decorator的一个类变量,你可以访问Decorator中的任何方法。这就使你得以改变对象的状态了。
  
  图1中的Decorator类不一定是接口或抽象类。如果你的程序不是很复杂,你可以将其转化为一个具体的Decorator类。
  
  举个例子,考虑这样一个简单的消息传递程序,其主要部分是Messenger接口及其实现类MessengerImpl。让我们假设MessengerImpl对象来自于一个工厂,因此你不能改变其状态。如果你准备增加或改变Messenger对象的功能,你可以创建一个MessengerDecorator类。图2是此例子的类图。
  
 

  
图2:Messenger装饰类

  
  我们来看程序的代码。列表1给出了Messenger接口的代码,列表2是MessengerImpl类的代码。
  
  列表1:Messenger接口
  
  public interface Messenger { public String getMessage();}
  
  列表2:MessengerImpl类
  
  public class MessengerImpl implements Messenger { private String message;
  public MessengerImpl(String message) {  this.message = message;
  } public String getMessage() {  return message;
  }
  }
  
  Messenger对象由一个名为MessengerFactory的工厂创建,如列表3所示。
  
  列表3:MessengerFactory类
  
  public class MessengerFactory {
  public static Messenger getMessenger()
  {
  return new MessengerImpl("secrets");
  }
  }
  
  对每一个所创建的Messenger对象,此工厂通过某个未知的操作,初始化了getMessage()方法所返回的字符串。换句话说,你不能自己创建Messenger对象。
  
  在程序中,Messenger对象的主要用途是被传递给一个名为Util的类中的broadcast()静态方法。列表4是Util类的代码。
  
  列表4:Util类
  
  public class Util {
  public static void broadcast(Messenger messenger) {
  System.out.print(messenger.getMessage());
  }
  // other methods here}
  
  在你自己的类中,你可能会有这样的代码:
  
  Messenger messenger = MessengerFactory.getMessenger();
  Util.broadcast(messenger);
  
  假设你希望对broadcast()方法所打印出的消息做一小改动。你拟将其转为大写,怎么做?表面上看,你可以继承Messenger,实例化其子类,并将返回的对象传给Util.broadcast()。但是,这种做法毫无意义,因为只有工厂才知道如何初始化Messenger对象,并通过其getMessage()方法返回正确的值。
  
  使用装饰模式,你可以创建一个MessengerDecorator类,如列表5所示。
  
  列表5:MessengerDecorator类
  
  public class MessengerDecorator implements Messenger { priva

[1] [2] 下一页


  • 上一个Java:
  • 下一个Java:
  •  
    热门文章
    推荐文章
    关于我们 | 发展历程 | 网站地图 | 广告服务 | 招贤纳士 | 战略合作 | 友情链接 | 著作声明 | 联系我们
    Copyright © 2002-2007 SYUE All rights reserved.
    E_mail:Admin@Syue.Com 皖ICP备05004589号
    未经授权禁止转载、摘编、复制或建立镜像.如有违反,追究法律责任.
    传世私服 传奇世界私服 天龙八部私服 bet365 传世私服 天龙八部私服 热血江湖私服 英雄合击传奇私服 热血江湖私服 bet365 bet365