📄 《struts 入门教学》-java中文站(www_java-cn_com).htm
字号:
bean。不管字段实际上是显示在哪个页面上。同样的,同一表单的不同的页面应该提交到相同的Action类。如果你遵照这个建议,在大多数情况下,页面设计者可以重新组织不同页面中的字段而不需要改变处理逻辑。
<BR>2.4 系统状态Beans
<BR>系统的实际状态通常表示为一组一个或多个的JavaBeans类,其属性定义当前状态。例如,一个购物车系统包括一个表示购物车的bean,这个bean为每个单独的购物者维护,这个bean中包括(在其它事物之中)一组购物者当前选择购买的项目。分别地,系统也包括保存用户信息(包括他们的信用卡和送货地址)、可获得项目的目录和它们当前库存水平的不同的beans。
<BR>对于小规模的系统,或者对于不需要长时间保存的状态信息,一组系统状态beans可以包含所有系统曾经经历的特定细节的信息。或者经常是,系统状态beans表示永久保存在一些外部数据库中的信息(例如CustomerBean对象对应于表
CUSTOMERS 中的特定的一行),在需要时从服务器的内存中创建或清除。在大规模应用程序中,Entity EJBs也用于这种用途。
<BR><BR>2.5 商业逻辑Beans
<BR>你应该把你的应用程序中的功能逻辑封装成对为此目的设计的JavaBeans的方法调用。这些方法可以是用于系统状态beans的相同的类的一部分,或者可以是在专门执行商业逻辑的独立的类中。在后一种情况下,你通常需要将系统状态beans传递给这些方法作为参数处理。
<BR>为了代码最大的可重用性,商业逻辑beans应该被设计和实现为它们不知道自己被执行于web应用环境中。如果你发现在你的bean中你必须import一个
javax.servlet.* 类,你就把这个商业逻辑捆绑在了web应用环境中。考虑重新组织事物使你的 Action
类(Controller任务的一部分,在下面描述)翻译所有从HTTP请求中请求被处理为对你的商业逻辑beans属性set方法调用的信息,然后可以发出一个对
execute() 的调用。这样的一个商业逻辑类可以被重用在除它们最初被构造的web应用程序以外的环境中。
<BR><BR>依赖于你的应用程序的复杂度和范围,商业逻辑beans可以是与作为参数传递的系统状态beans交互作用的普通的JavaBeans,或者使用JDBC调用访问数据库的普通的JavaBeans。而对于较大的应用程序,这些beans经常是有状态或无状态的EJBs。
<BR><BR>2.6 题外话: 访问关系数据库 <BR>很多web应用程序利用一个关系数据库(通过一个JDBC
driver访问)来保存应用程序相关的永久数据。其它应用程序则使用Entity
EJBs来实现这个目的,他们委派EJBs自己来决定怎样维护永久状态。如果你是使用EJBs来实现这个目的,遵照EJB规范中描述的客户端设计模式。
<BR>对于基于直接数据库访问的web应用程序,一个普通的设计问题是当需要访问低层数据库时怎样产生一个适当的JDBC连接对象。解决这个问题有几种方法
-- 以下原则描述了推荐的一种方法:
<BR><BR>创建或得到一个允许一组数据库连接被多个用户共享的ConnectionPool类。Struts(当前)没有包括这样的一个类,但是有很多这样的类可以得到。
<BR>当应用程序初始化时,在应用程序展开(deployment)描述符中定义一个有一个“启动时加载”值的servlet。我们将把这个servlet叫做
启动 servlet。在大多数情况下,这个servlet不需要处理任何的请求,所以没有一个 <servlet-mapping>
会指向它。 <BR>在启动servlet的 init() 方法中,配置并初始化一个ConnectionPool类的实例,将其保存为一个servlet
context属性(从JSP的观点看等同于一个application范围的bean)。通常基于传递给启动servlet初始化参数来配置联接缓冲池是很方便的。
<BR>在启动servlet的 destroy()
方法中,包含了释放联接缓冲池所打开的联接的逻辑。这个方法将在servlet容器结束这个应用程序的时候被调用。 <BR>当 Action
类需要调用一个需要数据库联接的商业逻辑bean中的方法(例如“insert a new customer”)时,将执行下面的步骤:
<BR>为这个web应用程序从servelt context属性中得到一个联接缓冲池对象。 <BR>调用联接缓冲池对象的 open()
方法来得到一个在 Action 类调用中使用的联接。 <BR>调用商业逻辑bean中合适的方法,将数据库联接对象作为一个参数传递给它。
<BR>调用分配的联接中的 close() 方法,这将引起这个联接为了以后其它请求的重用被返回到缓冲池中。
<BR>一个通常的编程错误是忘记了把数据库联接返回给缓冲池,这将最终导致用完所有的联接。一定要确信 Action
类的逻辑总是返回联接,甚至在商业逻辑bean抛出一个违例时。
<BR>遵照上面推荐的设计模式意味着你能够编写你的商业逻辑类而不需要担心它们怎样得到一个JDBC联接来使用--
简单地在任何需要访问数据库的方法中包含一个Connection参数。当你的商业逻辑类在一个web应用程序中被利用时,分配和释放适当的联接是
Action
类的责任。当你使用相同的商业逻辑类时,例如,在一个批处理工作中,提供一个适当的联接是那个应用程序的责任(这不需要从缓冲池中获得,因为大多数批处理工作运行于一个单线程环境中)。
<BR>3. 创建View组件 <BR>3.1 概述 <BR>这一章集中于创建应用程序中的 View
组件的任务,主要使用JSP技术建立。特别的,Struts除了提供了与输入表单的交互外还提供了建立国际化应用程序的支持。几个其它的与View相关的主题也被简单地讨论。
<BR>3.2 国际化消息
<BR>几年之前,应用程序开发者能够考虑到仅仅支持他们本国的只使用一种语言(或者有时候是两种)和通常只有一种数量表现方式(例如日期、数字、货币值)的居民。然而,基于web技术的应用程序的爆炸性增长,以及将这些应用程序展开在Internet或其它被广泛访问的网络之上,已经在很多情况下使得国家的边界淡化到不可见。这种情况转变成为一种对于应用程序支持国际化(经常被称做“i18n”,因为18是字母“i”和字母“n”之间的字母个数)和本地化的需求。
<BR>Struts建立于Java平台之上为建立国际化和本地化的应用程序提供帮助。需要熟悉的关键概念是: <BR><BR>Locale -
基础的支持国际化的Java类是 java.util.Locale 。每个 Locale
代表一个特别的国家和语言选择(加上一个可选的语言变量),以及一套格式假定,例如数字和日期等等。 <BR>ResourceBundle -
java.util.ResourceBundle 类提供支持多种语言消息的基本工具。查看文档中关于ResourceBundle
类以及你的JDK版本的文档包中关于国际化的更多内容。 <BR>PropertyResourceBundle - 一个 ResourceBundle
类的标准实现允许你使用与初始化properties文件同样的“name=value”语法来定义资源。这对于使用为用于一个web应用程序的消息准备资源包是非常方便的,因为这些消息通常都是面向文本的。
<BR>MessageFormat - java.text.MessageFormat
类允许你使用运行时指定的参数替换一个消息字符串中的一部分(在这种情况下,是一个从一个资源包得到的消息)。这在你创建一个句子的场合中是有用的,但是词会以不同的语言按照不同的顺序出现。消息中的占位符字符串{0}用第一个运行时参数替换,{1}用第二个运行时参数替换,以此类推。
<BR>MessageResources - Struts的类 org.apache.struts.util.MessageResources
使你能够将一套资源包视做一个数据库,并且允许你为一个特定的Locale(通常是与当前用户相对应)请求一个特定的消息,而不是为服务器运行在其中的缺省的Locale请求消息。
<BR>对于一个国际化的应用程序,遵照JDK文档包中国际化文档所描述的步骤来创建一个包含每种语言的消息的属性文件。下面举一个例子说明。
<BR>假设你的源代码建立在包 com.mycompany.mypackage
中,因此它保存于一个叫做(相对于你的源目录)com/mycompany/mypackage 的目录中。为创建一个叫做
com.mycompany.mypackage.MyResources 的资源包,你应该在目录 com/mycompany/mypackage
中创建下列文件: <BR><BR>MyResources.properties -
包含你的服务器的缺省语言的消息。如果你的缺省语言是英语,你可能有一个这样的条目: <BR>prompt.hello=Hello
<BR>MyResources_xx.properties -
包含ISO语言编程为“xx”(查看ResourceBundle的Java文档页面得到一个当前列表的联接)的同样的消息。对于上面的消息的法语版,你可以有这个条目:
<BR>prompt.hello=Bonjour <BR>你可以有你需要的任意多的语言的资源包文件。
<BR>当你在web应用程序展开描述符中配置controller
servlet时,你需要在一个初始化参数中定义的一件事是应用程序的资源包的基础名。在上述的情况中,这应该是
com.mycompany.mypackage.MyResources 。 <BR>3.3 表单和FormBean的交互
<BR>大部分web开发者曾经使用HTML的标准性能来建立表单,例如使用 <input>
标记。用户希望交互程序具有一定的行为,这些期待中的一个与错误处理有关 -- 如果用户出现一个错误,应用程序应该允许他们仅仅修改需要修改的部分 --
而不需要重新敲入当前页面或表单中的任何其它信息。
<BR>使用标准的HTML和JSP编程来完全实现这个期望是单调而繁重的。举例来说,一个用户名字段的输入元素看起来可以象是这样(在JSP中)
<BR><BR><input type="text" name="username" <BR>value="<%=
loginBean.getUsername() %>">
<BR>这很难敲对,会把没有编程概念的HTML开发者搞糊涂,并且会在HTML编辑器中造成问题。取而代之的是,Struts提供了一种全面的基于JSP
1.1的定制标记库功能的机制来建立表单。上面的情况使用Struts处理后将象是这样: <BR><struts:text
name="username"/> <BR>没有必要再显式地涉及到从中获得初始值的JavaBean。这将由框架自动处理。 <BR>3.3.1
使用Struts建立表单
<BR>一个完整的注册表单将演示Struts相对于直接使用HTML和标准的JSP功能怎样极大地减轻了处理表单的痛苦。考虑以下称为logon.jsp的页面(来自Struts的例子程序):
<BR><BR>代码: <BR><BR><BR><%@ page language="java" %> <BR><%@
taglib uri="/WEB-INF/struts.tld" prefix="struts" %>
<BR><BR><html> <BR><head> <BR><title><struts:message
key="logon.title"/></title> <BR><body bgcolor="white">
<BR><BR><struts:errors/> <BR><BR><struts:form action="logon.do"
name="logonForm" <BR>type="org.apache.struts.example.LogonForm"/>
<BR><table border="0" width="100%"> <BR><tr> <BR><th
align="right"> <BR><struts:message key="prompt.username"/>
<BR></th> <BR><td align="left"> <BR><struts:text
name="username" size="16"/> <BR></td> <BR></tr>
<BR><tr> <BR><th align="right"> <BR><struts:message
key="prompt.password"/> <BR></th> <BR><td align="left">
<BR><struts:password name="password" size="16"/> <BR></td>
<BR></tr> <BR><tr> <BR><td align="right">
<BR><struts:submit> <BR><struts:message key="button.submit"/>
<BR></struts:submit> <BR></td> <BR><td align="right">
<BR><struts:reset> <BR><struts:message key="button.reset"/>
<BR></struts:reset> <BR></td> <BR></tr>
<BR></table> <BR></struts:form> <BR><BR></body>
<BR></html> <BR><BR><BR><BR>下面的条目基于这个例子演示在Struts中处理表单的关键的特性:
<BR>taglib指令告诉JSP页面编译器从哪里找到Struts标记库的 标记库描述符
。在这种情况下,我们使用struts作为前缀来标识来自这个库中的标记,但是可以使用任何你想用的前缀。 <BR>这个页面使用了几个 message
标记来从一个包含有这个应用程序所有资源的 MessageResources
对象中查找国际化的消息字符串。为了让这个页面能够工作,以下的消息关键字必须在这些资源中被定义: <BR>logon.title - 注册页面的标题
<BR>prompt.username - 一个 “Username:” 提示字符串 <BR>prompt.password - 一个
“Password:” 提示字符串 <BR>button.submit - “Submit”按钮的标签 <BR>button.reset -
“Reset”按钮的标签 <BR>当用户注册时,应用程序可以在用户的session中保存一个 Locale 对象。这个 Locale
将用来选择适当语言的消息。这使得给用户一个切换语言的可选项实现起来变的容易了 -- 仅仅改变保存的 Locale 对象,所有的消息就会自动切换。
<BR>errors 标记显示由一个商业逻辑组件保存的任何出错消息,或者如果没有出错消息保存就什么都没有。这个标记将在下面做深入的描述。
<BR>form 标记基于指定的属性对一个HTML <form> 元素进行处理。它也将所有在这个表单中的字段与一个保存在关键字
logonForm
下的session范围的FormBean相关联。这个bean用来为所有的具有与bean中的属性名匹配的名字的输入字段提供初始值。如果适当的bean没有找到,一个新的bean将会被自动建立,使用指定的Java类名。
<BR>text 标记对一个类型为“text”的HTML <input>
元素进行处理。在这种情况下,占据浏览器屏幕的字符位置的数字也被指定。当页面被执行时,是相对应的bean的 username 属性的当前值(也就是
getUsername() 的返回值)。 <BR>password
标记使用方法类似。不同之处是当用户敲入他们的口令时浏览器将回应星号字符,而不是输入值。 <BR>submit 和 reset
标记在表单低部生成相应的按钮。每个按钮的文本标签使用 message 标记建立,同时带有提示,这样这些值就是国际化的。 <BR>3.3.2
输入字段类型支持 <BR>Struts为所有以下类型的输入字段定义了标记,带有与其相应的参考信息的超联接。 <BR>checkboxes
<BR>hidden 字段 <BR>password 输入字段 <BR>radio 按钮 <BR>reset 按钮 <BR>select
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -