首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

Struts 2.2.3.1指南:核心开发指南(第部分)

2013-01-02 
Struts 2.2.3.1指南:核心开发指南(第一部分)Struts 2.2.3.1指南这个深入的指南主要关注框架的特定领域,例

Struts 2.2.3.1指南:核心开发指南(第一部分)

Struts 2.2.3.1指南
这个深入的指南主要关注框架的特定领域,例如:视图、核心框架、以及第三方的扩展。
第1章 核心开发指南
Struts 2使用了三个核心类型来处理请求:interceptor、action、result。每个类型都可以通过XML或注解来配置。
1.1 教程
请查看教程文档
1.2 使用Struts 2开发应用程序
1.2.1 概述
此框架文档是为积极主动的Web开发人员编写的,并假设他们已经了解了关于如何构建Java Web应用程序的工作知识。更多关于顶层的基本要素,查看关键技术入门。
1.2.1.1 Apache Struts 2框架概述
(1)Web浏览器请求一个资源(/mypage.action、/reports/myreport.pdf、等等);
(2)Filter Dispatcher查看这个请求并确定适当的Action;
(3)拦截器自动把通用功能应用于这个请求,例如:工作流、验证和文件上传的处理;
(4)执行Action方法,通常是把信息存入数据库或从数据库检索信息;
(5)Result把输出渲染到浏览器,可能为HTML、图片、PDF、或其它东西。
1.2.1.2 Struts 2标签概述
Struts标签帮助你以最少的代码创建富Web应用程序。通常,一个应用程序的大部分编码工作都在页面上。Struts标签通过减少代码来减少工作。
<% User user = ... %>
<form action="Profile_update.action" method="post">
??? <table>
??? ??? <tr>
??? ??? ??? <td align="right"><label>First name:</label></td>
??? ??? ??? <td><input type="text" name="user.firstname" value="<%=user.getFirstname() %> /></td>
??? ??? </tr>
??? ??? <tr>
??? ??? ??? <td><input type="radio" name="user.gender" value="0" id="user.gender0"
??? ??? ??? ??? <% if (user.getGender()==0) { %> checked="checked" %> } %> />
??? ??? ??? <label for="user.gender0">Female</label>
??? ??? </tr>
??? </table>
</form>
...

回顾以上标记,很容易看出为什么没有现代框架的帮助Java Web的开发是很困难的。到目前为止,我们只为两个控件进行了编码,还有六个控件需要编码。让我们使用Struts标签来重写并完成这个表单。
<s:actionerror/>
<s:form action="Profile_update" validate="true">
??? <s:textfield label="Username" name="username"/>
??? <s:password label="Password" name="password"/>
??? <s:password label="(Repeat) Password" name="password2"/>
??? <s:textfield label="Full Name" name="fullName"/>
??? <s:textfield label="From Address" name="fromAddress"/>
??? <s:textfield label="Reply To Address" name="replyToAddress"/>
??? <s:submit value="Save" name="Save"/>
??? <s:submit action="Register_cancel" value="Cancel" name="Cancel"?
??? ??? onclick="form.onsubmit=null"/>
</s:form>

Struts标签还支持验证和国际化等优秀特性。因此,不仅仅是减少了代码,而且还有更多功能。与两个传统控件具有差不多相同代码量的情况下,Struts标签可以创建一个包含八个控件的完整的数据输入表单。不仅仅减少了代码,而且代码更易于阅读和维护。
1.2.1.3 Struts配置概述
Web应用程序使用一个部署描述符来初始化资源,例如:过滤器和监听器。Web部署描述符的格式为XML文档,且名称是web.xml。Struts可以通过扫描在web.xml文件中声明的Java包中的类来初始化它的资源,你也可以通过struts.xml配置文件来完全控制配置。这些资源包括把输入指向服务端的Action类的Action映射,以及选择输出页面的Result类型。以下是一个典型的登录工作流的struts.xml配置:
<struts>
??? <package name="default" extends="struts-default">
??? ??? <action name="Logon" type="redirectAction">Welcome</result>
??? ??? ??? <result type="redirectAction">MainMenu</result>
??? ??? ??? <result name="expired" type="chain">ChangePassword</result>
??? ??? </action>

??? ??? <action name="Logoff" %>
<%
??? String bookIdStr = request.getParameter("bookId");
??? int bookId = (bookIdStr == null || "".equals(bookIdStr.trim())) ?
??? ??? 0 : Integer.parseInt(bookIdStr);
??? Book book = BookManager.getBook(bookId);
??? if (book != null) {
??? ??? out.println(book.toJSONString());
??? ??? System.out.println("itis: " + book.toJSONString());
??? }
%>
在示例代码中,你可以使用System.out.println来返回一个JSON数据流来作为响应。关于这个技术的更多详细信息,请查看文章:使用Dojo和JSON来构建Ajax应用程序。
1.2.3 依赖注入
依赖注入移除了创建对象的责任,并把对象关联从对象本身转移到了工厂。工厂通常由一个IOC(控制反转)容器提供。关于更多IOC容器的概述,以及依赖注入模式,请查看Martin Fowler的文章。

在内部,框架使用自身的类似于Google Guice依赖注入容器,这两个最开始都是由Bob Lee开发的。插件可以用于把应用程序和其它IOC容器整合在一起,例如:Spring插件,Plexus插件。应用程序甚至还可以使用一个Google Guice的本地副本来满足依赖注入的需要。

Action仍然可以通过Spring的配置,以Spring插件的方式来实例化,但是Spring完全是可选的。

Struts 2不支持WebWork 2.1中使用的WebWork/XWork IOC容器。
1.2.4 性能分析
性能分析(Profiling)软件用于查找程序执行中的瓶颈。除了IDE提供的性能分析服务和标准的性能分析器外,框架还提供了内部的性能分析支持。
1.2.4.1 性能分析切面
Struts 2的性能分析切面包括以下内容:
(1)ActionContextCleanUp
(2)FreemarkerPageFilter
(3)DispatcherFilter
(3.1)Dispatcher
(3.1.1)创建DefaultActionProxy
(3.1.1.1)创建DefaultActionInvocation
(3.1.1.1.1)创建Action
(3.1.2)执行DefaultActionProxy
(3.1.2.1)调用DefaultActionInvocation
(3.1.2.1.1)调用Interceptors
(3.1.2.1.2)调用Action
(3.1.2.1.3)调用PreResultListener
(3.1.2.1.4)调用Result
1.2.4.2 用法
要启用性能分析,首先要确保把profiling拦截器应用于action,例如:
<action ... >
??? ...
??? <interceptor-ref name="profiling">
??? ??? <param name="profilingKey">profiling</param>
??? </interceptor-ref>
??? ...
</action>

然后使用以下方法中的一种来开启性能分析:
(1)通过系统属性来激活
-Dxwork.profile.activate=true
这可以在容器的启动脚本中这么做,例如在Tomcat的catalina.sh的CATALINA_OPTS中,或使用在Jetty中使用java -Dxwork.profile.activate=true -jar start.jar

(2)通过代码来激活
UtilTimerStack.setActivate(true);
这可以在以下方式中这么做:在一个静态块中,在一个使用lazy-init="false"的Spring Bean中,在一个使用init-on-startup数字值的Servlet中,在一个Filter或Listener的初始化方法中,等等。

(3)通过参数来激活
http://host:port/context/namespace/someAction.action?profiling=true

(4)修改激活参数的名称
把profiling拦截器的profilingKey属性设置位期望名称:
<action ... >
??? ...
??? <interceptor-ref name="profiling">
??? ??? <param name="profilingKey">profiling</param>
??? </interceptor-ref>
??? ...
</action>
通过一个参数,需要把struts.devMode设为true来激活性能分析。
1.2.4.3 过滤性能分析信息
通过如下系统属性,可以过滤出性能分析日志:
-Dxwork.profile.mintime=10000

通过这个xwork.profile.mintime属性,只有在执行时间超过xwork.profile.mintime系统属性指定的时间时,才能记录性能分析信息。如果你没有指定这个属性,就会把这个属性假设为0,因此会记录所有性能分析的信息。
1.2.4.4 编写性能分析代码
也可以在Web应用程序中扩展Struts 2提供的性能分析特性。

使用UtilTimerStack的push和pop
String logMessage = "Log message";
UtilTimerStack.push(logMessage);
try {
??? // do some code
} finally {
??? UtilTimerStack.pop(logMessage); // this needs to be the same text as above
}

使用UtilTimerStack的ProfileBlock模板
String result = UtilTimerStack.profile("purchaseItem: ",
??? new UtilTimerStack.ProfilingBlock<String>() {
??? ??? public String doProfiling() {
??? ??? ??? // do some code
??? ??? ??? return "Ok";
??? ??? }
??? });
1.2.4.5 性能分析的日志文件
性能分析结果是在名为com.opensymphony.xwork2.util.profiling.UtilTimerStack的日志记录器下,使用commons-logging来记录的。依靠底层的日志实现,假设是Log4j,可以直接把日志记录在不同的文件中,通过电子邮件发送给别人或存储在数据库中。
1.2.5 调试
现在的IDE对调试提供了很好的支持。此外,框架也提供了在运行时检查特定框架对象的支持。

Debugging拦截器提供了三种调试模式来深入了解页面背后的数据。xml模式把相关的框架对象格式化为XML文档。console模提供了接受运行时表达式入口的OGNL命令行。browser模式添加了一个用于显示值栈(Value Stack)中的对象的交互页面,这需要Dojo插件。

要使用调试,首选需要确保在struts.properties或struts.xml文件中,把struts.devMode属性设置为true。例如:
<constant name="struts.devMode" value="true" />

然后,无论什么时候,一个页面需要调试时,把?debug=xml或?debug=console或?debug=browser添加到URL中。
- <debug>
? <parameters />
- <context>
- <struts.actionMapping>
? <class>class org.apache.struts2.dispatcher.mapper.ActionMapping</class>
? <name>showcase</name>
? <namespace>/</namespace>
? </struts.actionMapping>
? <attr />
? <__devMode>true</__devMode>
? <report.conversion.errors>false</report.conversion.errors>
? </context>
? <request />
? <session />
- <valueStack>
- <value>
? <actionErrors />
? <actionMessages />
? <class>class com.opensymphony.xwork2.ActionSupport</class>
? <errorMessages />
? <errors />
? <fieldErrors />
- <locale>
? <ISO3Country>USA</ISO3Country>
? <ISO3Language>eng</ISO3Language>
? <class>class java.util.Locale</class>
? <country>US</country>
? <displayCountry>United States</displayCountry>
? <displayLanguage>English</displayLanguage>
? <displayName>English (United States)</displayName>
? <displayVariant />
? <language>en</language>
? <variant />
? </locale>
? </value>
- <value>
? <class>class com.opensymphony.xwork2.DefaultTextProvider</class>
? </value>
? </valueStack>
? </debug>

对于?debug=xml,使用IE或在FireFox中使用IE tab。
对于?debug=console,你可能需要放开阻止任何弹出窗口的程序。
1.2.6 开发模式
1.2.6.1 devMode
Struts 2中有一个名为devMode的设置(开发模式,可以在struts.properties中设置为true或false)。当启用这个设置时,Struts 2会提供额外的日志和调试信息,可以可以显著地加快开发。

你也可以在struts.xml文件中设置这个常量:<constant name="struts.devMode" value="true" />。这是首选方法,更多信息,请查看常量配置。
1.2.6.2 它做了什么
(1)启用后,每次请求Struts 2都会重新加载你的资源包,这意味着你可以修改.properties文件,保存,然后查看修改对下次请求的影响。注意:这个选项也可以通过struts.i18n.reload=true来进行单独设置。
(2)它也会在每次请求时重新加载xml配置文件struts.xml,验证文件,等等。这对于测试或微调配置来说是非常有用的,不需要每次都重新部署应用程序。
注意:这个选项也可以通过struts.configuration.xml.reload=true来进行单独设置。
(3)第三,或许这个设置是鲜为人知的,因此它是造成更多混乱的原因:它会提高调试或通常可以忽略的问题的错误级别。例如,当你提交了一个不能在someUnknownField action上设置的字段时,它通常会被忽略。然而,当你处于开发模式时,一个异常将会被抛出,告诉你提交了一个非法字段。这对于调试或测试大表单来说是非常有用的,但是这也会混淆,如果你依赖的请求参数没有被设置到action上,哪一个是你直接用于视图层的呢。警告:不好的实践,你应该总是验证来自web的输入。
1.2.6.3 不要忘记了
默认情况下,开发模式是被禁用的,因为对于每个请求整个配置都会被重新加载,所以它对性能有很大影响。

热点排行