JavaWeb编程技术第6章Web组件重用与JavaBeans6.1静态包含6.2动态包含6.3JavaBean概述6.4通过JSP动作使用JavaBean6.5在Servlet中使用JavaBean6.6从脚本元素中访问JavaBean6.7JavaBean的其他特性6.8MVC设计模式6.1静态包含6.1.1使用include指令6.1.2从被包含的页面中访问变量6.1.3静态包含的限制6.1.4使用包含设计页面布局6.1.1使用include指令静态包含使用include指令,语法:%@includefile=relativeURL%文件可以是任何基于文本的文件,如HTML、JSP、XML文件,甚至是简单的.txt文件。相对URL是指它不能含有协议、主机名或端口号。它可以是相对于当前JSP文件的路径,即不以”/”开头,或者是相对于Web应用程序文档根目录的路径,即以”/”开头。例如:%@includefile=other.jsp%静态包含是在JSP页面转换阶段将另一个文件的内容包含到当前JSP文件中产生一个servlet。include指令的工作方式每个页面都可以访问在另一个页面中定义的变量。它们也共享所有的隐含对象。程序hello.jsp程序response.jsp6.1.2从被包含的页面中访问变量(1)在转换阶段不进行任何处理,这意味着file属性值不能是表达式,因此下面对include指令的使用是非法的:%StringmyURL=copyright.html;%%@includefile=%=myURL%%(2)不能通过file属性值向被包含的页面传递参数,因为请求参数是请求的一个属性,它在转换阶段没有任何意义。下面例子中的file属性值是非法的:%@includefile=other.jsp?name=honey%6.1.3静态包含的限制(3)被包含的页面可能不能单独编译。如果一个页面使用了另一个页面声明的变量,该页面就不能单独编译。一般来说,最好避免这种相关性,可以使用隐含变量pageContext共享对象,通过使用pageContext的setAttribute()和getAttribute()方法实现。6.1.4使用包含设计页面布局标题导航菜单主体内容广告脚注tableborder=0cellpadding=0cellspacing=0width=640trtdcolspan=3!--这里是标题区域--/td/trtrtdwidth=160!--这里是导航菜单--/tdtdwidth=480!--这里是主体内容--/tdtdwidth=160!--这里是广告内容--/td/trtrtdcolspan=3!--这里是脚注内容--/td/tr/tableindex.jspheader.htmlffooter.jspf6.2动态包含6.2.1使用jsp:include标准动作6.2.2向动态包含的组件传递参数6.2.3与动态包含的组件共享对象6.2.4使用jsp:forward标准动作其语法如下所示:jsp:includepage=relativeURLflush=true/page属性是必须的,其值必须是相对URL,并指向任何静态或动态web组件,包括servlet。也可以是请求时表达式,例如:%StringpageURL=other.jsp;%jsp:includepage=%=pageURL%/flush属性是指在将控制转向被包含页面之前是否刷新当前页面的缓冲区,默认false。6.2.1使用jsp:include动作工作方式结构1%RequestDispatcherview=request.getRequestDispatcher(other.jsp);view.include(request,response);%结构2%pageContext.include(other.jsp);%结构3jsp:includepage=other.jspflush=true/在jsp:include动作中可以使用jsp:param/动作向被包含的页面传递参数。下面的代码向被包含的页面(somePage.jsp)传递两个参数:jsp:includepage=somePage.jspjsp:paramname=name1value=value1/jsp:paramname=name2value=value2//jsp:include在被包含的页面中使用request隐含对象的getParameter()方法获得传递来的参数。%=request.getParameter(“name1”)6.2.2使用jsp:param传递参数在jsp:include元素中可以嵌入任意多的jsp:param元素。value的属性值也可以像下面这样使用请求时属性表达式来指定:jsp:includepage=somePage.jspjsp:paramname=name1value=%=someExpr1%/jsp:paramname=name2value=%=someExpr2%//jsp:include通过jsp:param动作传递的名/值对存在于request对象中并只能由被包含的组件使用,这些参数的作用域是被包含的页面,在被包含的组件完成处理后,容器将从request对象中清除这些参数。动态包含的页面是单独执行的,因此它们不能共享在包含页面中定义的变量和方法。然而,它们处理的请求对象是相同的,因此可以共享属于请求作用域的对象.hello.jsp6.2.3与动态包含的组件共享对象使用jsp:forward动作把请求转发到其他组件,然后由转发到的组件把响应发送给客户该动作的格式为:jsp:forwardpage=relativeURL/page属性的值为转发到的组件的相对URL,它可以使用请求时属性表达式。它与jsp:include动作的不同之处在于,当转发到的页面处理完输出后,并不将控制转回主页面。使用jsp:forward动作,主页面也不能包含任何输出。工作方式6.2.5使用jsp:forward动作在功能上jsp:forward的语义与RequestDispatcher接口的forward()方法的语义相同,因此下面三个结构是等价的:【结构1】%RequestDispatcherview=request.getRequestDispatcher(other.jsp);view.forward(request,response);%【结构2】%pageContext.forward(other.jsp);%【结构3】jsp:forwardpage=other.jsp/JavaApplet是主要应用领域,它是可嵌入到HTML页面中运行的Java程序。在HTML页面中使用applet标签把Applet嵌入到页面中。同样,也可以将Applet嵌入到JSP页面中,这时应该使用jsp:plugin动作,它的格式如下:6.3在JSP页面中使用JavaAppletjsp:plugintype=bean|applet“code=objectCodecodebase=objectCodebase{width=width}{height=height}{jsp:params{jsp:paramname=paramNamevalue=”paramValue/}+/jsp:params}{jsp:fallbackarbitrary_text/jsp:fallback}/jsp:plugin%@pagecontentType=text/html;charset=gb2312%htmlheadtitleAppletDemo/title/headbodybgcolor=white现在的时间是:brjsp:plugintype=appletcode=ClockDemo.classwidth=200height=50/jsp:plugin/body/htmlClockDemo.java在MVC设计模式中常用JavaBeans来封装业务逻辑、数据库操作等等,从而很好地实现业务逻辑和表示逻辑的分离,使系统具有更好的健壮性和灵活性。本节主要内容:6.4.1什么是JavaBeans?6.4.2序列化JavaBeans6.4JavaBeans概述JavaBean是Java平台的组件技术。JavaBean就是使用Java语言定义的类,而这种类的设计需要遵循Sun制定的JavaBean规范文档中描述的有关约定。与EJB完全不是一回事。在Java模型中,通过JavaBean可以无限扩充Java程序的功能。对于程序员来说,最好的一点就是JavaBean可以实现代码的重复利用,另外对于程序的易维护性等也有很大的意义。在JSP程序中常用JavaBean来封装业务逻辑、数据库操作等等,可以很好地实现业务逻辑和表示逻辑的分离,使得系统具有更好的健壮性和灵活性。6.4.1什么是JavaBeans?遵循下面3个规范的Java类作为JavaBean类必须是public的;类必须具有无参数的public构造方法,JavaBeans类的成员变量一般称为属性(property)。对每个属性访问权限一般定义为private或protected,而不是定义为public的。注意:属性名必须以小写字母开头。对每个属性,一般定义两个public方法,它们分别称为访问方法(getter)和修改方法(setter),允许容器访问和修改bean的属性。publicStringgetColor();publicvoidsetColor(String);一个例外是当属性是boolean类型时,访问器方法应该定义为isXxx()形式。例如,假设JavaBean有一个boolean型属性valid,则访问器方法应该定义为publicbooleanisValid()。除了访问方法和修改方法外,类中还可以定义其他的方法实现某种业务逻辑。也可以只为某个属性定义访问器方法,这样的属性就是只读属性。下面是一个简单的例子:CustomerBeanJavaBean命名惯例:UserBean、AccountBean。以区别一般的类,这样可以给协作的开发人员清晰的含义。JavaBean类存放在/WEB-INF/classes目录中/WEB-INF/lib目录中的JAR文件中。在JSP中使用这些类,使用page指令的import属性导入它们。%@pageimport=com.model.CustomerBean%JavaBean的优点在JSP页面中使用JavaBeans的代码简洁。JavaBeans也有助于增强代码的可重用性。它们是Java语言对象,充分利用该语言的面向对象的特征。JavaBean的序列化是将一个JavaBean实例转换成数据流并存储在文件中的过程,这样它的属性和值就被永久保存起来并在以后根据需要检索。序列化的过程是通过Java标准的对象序列化机制实现的。首先,JavaBean类必须实现java.io.Serializable接口使类能够被序列化;然后通过使用java.io.ObjectOutputStream类对bean实例序列化。6.4.2序列化JavaBeans序列化的beans被作为资源使用应该具有下面的要求:存储序列化bean的文件扩展名必须是.ser。例如,•如John.ser或Mary.ser。存储bean的文件必须存放在Web应用程序的类路