<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <include file="webwork-default.xml"/> <package name="default" extends="webwork-default"> <interceptors> <interceptor-stack name="defaultComponentStack"> <interceptor-ref name="component"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultStack"/> <action name="SimpleCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter"> <result name="success" type="dispatcher">/success.jsp</result> <interceptor-ref name="defaultComponentStack"/> </action> <!-- - Velocity implementation of the SimpleCounter. Also demonstrate a more verbose version of result element --> <action name="VelocityCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter"> <result name="success" type="velocity"> <param name="location">/success.vm</param> </result> <interceptor-ref name="defaultComponentStack"/> </action> <!-- - Different method can be used (processForm). --> <action name="formTest" class="com.opensymphony.webwork.example.FormAction" method="processForm" > <result name="success" type="dispatcher">/formSuccess.jsp</result> <result name="invalid.token" type="dispatcher">/form.jsp</result> <interceptor-ref name="defaultStack"/> <interceptor-ref name="token"/> </action> </package> </xwork>
<action name="formTest" class="com.opensymphony.webwork.example.FormAction" method="processForm">
zd是WebWork的基本工作单? 它正是定义了zd. zd通常有一个请?通常是点L? 或提交表?. 主要的action元素有两部分, 友好的名?在URL中引? 如saveForm.action)和对应的"处理(handler)"c?
可选的"method"属性告诉WebWork应当调用zd的哪个方? 如果你不填写method属? WebWork~省调用execute(). 如果zd没有execute()Ҏ, 也没有在xml中指定method属? WebWork抛出异?同样, 你也可以在表单中指定"actionName!something"来告诉WebWork调用"doSomething"Ҏ. 例如, "formTest!save.action"调用FormAction?save"Ҏ. 该方法必Lpublic且没有参?
public String save() throws Exception { ... return SUCCESS; }
zd的所有配|都可以用在"actionName!something"?截取? l果cd{?
<result name="missing-data" type="dispatcher"> <param name="location">/form.jsp</param> <param name="parameterA">A</param> <param name="parameterB">B</param> </result>
Result元素告诉WebWorkzd执行后下一步该做什? "name"属性对应活动execute() Ҏq回的结果代? "type"属性表CZ用哪个结果类?参见l果cd). 可以使用"param"元素向视图传递参?
<result-types> .... <result-type name="header" class="com.opensymphony.webwork.dispatcher.HttpHeaderResult"/> </result-types> <result name="no-content" type="header"> <param name="status">204</param> <param name="headers.customHeaderA">A</param> <param name="headers.customHeaderB">B</param> </result>
下面是WebWork内置的标准结果代?定义在Action接口?, 包括:
Action.SUCCESS = "success"; Action.NONE = "none"; Action.ERROR = "error"; Action.INPUT = "input"; Action.LOGIN = "login";
你可以扩充你认ؓ适合的结果代??missing-data"). 大多数情况下你只需使用SUCCESS和ERROR, SUCCESS前q到下一个页?
如果你只需要指?location"属? 可以使用写Ş?<result name="missing-data" type="dispatcher">/form.jsp</result>
参阅webwork-default.xml?a title="Result Types" href="file:///D:/%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6/webwork/webwork-2.2.4/docs/chinese/wikidocs/Result%20Types.html">Result Types以了解标准结果类?/p>
截取器允许定义活动执行前后的代码. 截取器是~写Web应用的强大工? 一些最常用的实现是:
<interceptors> <interceptor name="security" class="com.mycompany.security.SecurityInterceptor"/> <interceptor-stack name="defaultComponentStack"> <interceptor-ref name="component"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors>
要在zd中用它?
<action name="VelocityCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter"> <result name="success">...</result> <interceptor-ref name="defaultComponentStack"/> </action>
注意: 可以引用拦截器或栈的名字
更多l节参见截取?/font>.
WebWork支持JSP和Velocity作ؓ应用表示? 本例使用JSP文g. Webwork附带了标{ֺ(taglibs). 你可以在JSP中项lg一样用标{ֺ.下面是form.jsp的片?
<%@ taglib prefix="ww" uri="webwork" %> <html> <head><title>Webwork Form Example</title></head> <body> <ww:form name="myForm" action="'formTest'" namespace="/" method="POST"> <table> <ww:textfield label="First Name" name="'formBean.firstName'" value="formBean.firstName"/> <ww:textfield label="Last Name" name="'formBean.lastName'" value="formBean.lastName"/> <ww:submit value="Save Form"/> </table> </ww:form> </body>
处理l过如下:
Z易于理大规模开发活?包含大量zd和配|?, WebWork允许在xwork.xml中包含其他配|文?:
<xwork> <include file="webwork-default.xml"/> <include file="user.xml"/> <include file="shoppingcart.xml"/> <include file="product.xml"/> .... </xwork>
被包含文件必Mxwork.xml的格式相?h相同的doctype及其?q放|在c\径中(通常位于/WEB-INF/classes?WEB-INF/lib的jar文g?.
你的应用E序的基本包(base package)应该扩展?webwork-portlet-default ? 例如:
<include file="webwork-default.xml" /> <package name="view" extends="webwork-portlet-default" namespace="/view">
下面是在 portlet.xml 中ؓportlet配置portlet模式(mode) -> xwork命名I间(namespace)影射?init-param 元素. 单的? 你可以把portlet模式理解Z同的子应用程? q样它可以ؓ不同的portlet和portlet模式?xowrk.xml 中配|不同的命名I间(namespace):
Key | 描述 | 默认? |
---|---|---|
portletNamespace | q个portlet在xwork配置中的命名I间(namespace). 命名I间(namespace)在查找action时被优先考虑, 从而允许在同一个portlet应用E序中徏?host)多个portlet. 如果讑֮了这个参? 完整的命名空?namespace)会?/portletNamespace/modeNamespace/actionName | 默认命名I间. |
viewNamespace | xwork配置中视图portlet模式(view portlet mode)的命名空?namespace). | The default namespace. |
editNamespace | xwork配置中编辑portlet模式(edit portlet mode)的命名空?namespace). The namespace in the xwork config for the edit portlet mode. | 默认命名I间. |
helpNamespace | xwork配置中帮助portlet模式(help portlet mode)的命名空?namespace). | 默认命名I间. |
defaultViewAction | 在没有指定action名称? 视图portlet模式(view portlet mode)使用的默认action名称. | 默认? |
defaultEditAction | 在没有指定action名称? ~辑portlet模式(edit portlet mode)使用的默认action名称. | 默认? |
defaultHelpAction | 在没有指定action名称? 帮助portlet模式(help portlet mode)使用的默认action名称. | 默认? |
例子
<init-param> <!-- Portlet 命名I间 --> <name>portletNamespace</name> <value>/portletA</value> </init-param> <init-param> <!-- view portlet 的基本命名空?--> <name>viewNamespace</name> <value>/view</value> </init-param> <init-param> <!-- 在view portlet 模式下调用的默认action名称 --> <name>defaultViewAction</name> <value>index</value> </init-param>
q个 portlet.xml 的片断将会徏立一个命名空间ؓ /portletA/ 的portlet. q意味着所有对该portlet的请求将优先在此命名I间中寻找action. q一步说, _视图(view) portlet 模式会影射?/view 命名I间, q样一个对?myAction 的action的请求将会被转发C?/portletA/view/myAction 命名I间下的action? q也意味着如果没有h一个action, 那么对这个请求将会调用默认的action index.
Portlet规范描述一个portleth周期持lؓ两个阶段, event(zd) 阶段 ?render(渲染) 阶段. 假设q个portlet中有 event(zd) 阶段, 那么它将肯定先于 render(渲染) 阶段执行. Event(zd) 阶段一般用来改变应用程序的状? 在一个portlet? 典型情况是在form提交的时? Render(渲染) 阶段会准备和分zֈ视图(view). 推荐你将一个在 event(zd) 阶段执行的action的结?result)指向到另外一个在 render(渲染) 阶段执行的action? 后者用来负责派发到真正的视?
webwork-portlet-default 包定义了一个特D的默认l果cd(result type), 它负责执行一个Action执行的结果逻辑(result logic). 一? q包括include一个jspq行渲染, 或者ؓ当前的活?action准备一个渲?action.
q个l果cd有三U主要执行模?
在活动模式执行的action可以通过result配置中的query stringl渲染模式执行的action传递渲染参?
<result name="success">/displayCart.action?userId=${userId}</result>
q会一个叫?userId ?渲染参数 g递给要z֏到的action?userId 属?
q篇教程带你l历建立单portlet应用的流E? 使用Eclipse, JBoss Portal 2.2 ?WebWork Portlet框架.
q篇教程? 我们会使用 Eclipse 3.1.1, 可以从此处下?http://www.eclipse.org
JBoss Portal 2.2 可以在这里下?http://www.jboss.com/products/jbossportal/downloads.
一个Portlet应用与一般的web应用E序的打包方式基本相? 但是需要附加描q文? portlet.xml. 本教E的W一步是在eclipse里面建立目l构. 首先, 我们创徏q个 Java 目本n, 使用新徏目的向? 我们命名目?'MyPortlet'. 定选择?"Create separate source and output folders (创徏单独的源文g和输出目?"选项, 下一? 讄 'src' 源文件目录的输出目录(output folder)?MyPortlet/webapp/WEB-INF/classes'. 讲讲方便我们在完成项目的时候导出本目?WAR ?
New project wizard (新徏目向导)
New project wizard, cont (新徏目向导, l?
?build 应用E序之前, 我们需要添加一些需要的jar包到 build classpath ?WEB-INF/lib 目录? 首先, 创徏 WEB-INF/lib 目录, 然后下蝲 WebWork 2.2.1 发布包ƈv解压~到本地盘. 扑ֈ下面屏幕截图中的jar包ƈ它们放到新创徏?WEB-INF/lib 目录? 选择所有的jar? 炚w标右键选择 "Build Path(Build路径) -> Add to Build Path(dBuild路径)". 现在你的本地目应该看v来和屏幕截图中相?
Next thing we do is create a portlet.xml file in the WEB-INF folder. In this file, write the following:
我们下面要做的是?WEB-INF 目录中创Z?portlet.xml 文g. 在这个文件中, 写下如下内容:
<portlet-app version="1.0" xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"> <portlet> <description xml:lang="EN">My very first WebWork Portlet</description> <portlet-name>MyPortlet</portlet-name> <display-name xml:lang="EN">My first WebWork Portlet</display-name> <portlet-class>com.opensymphony.webwork.portlet.dispatcher.Jsr168Dispatcher</portlet-class> <init-param> <!-- 视图模式(view mode)的命名空?namespace). 映射到xwork配置中的命名I间 --> <name>viewNamespace</name> <value>/view</value> </init-param> <init-param> <!-- 在视图模式中调用的默认action名称 --> <name>defaultViewAction</name> <value>index</value> </init-param> <expiration-cache>0</expiration-cache> <supports> <mime-type>text/html</mime-type> </supports> <supported-locale>en</supported-locale> <portlet-info> <title>My very own WebWork Portlet</title> <short-title>WWPortlet</short-title> <keywords>webwork,portlet</keywords> </portlet-info> </portlet> </portlet-app>
?portlet.xml 文g讑֮q个 portlet 使用 com.opensymphony.webwork.portlet.dispatcher.Jsr168Dispatcher Portlet 实现. 它还告诉 Portlet 它会映射 视图 portlet 模式?XWork 配置中的 /view 命名I间, 我们在徏?building)我们?XWork action 的时候必ȝ记它. q有, 它告?portlet, 如果?portlet h中没有找C个action 参数, 被调用的默认 action ?"index" action, 它应该被攑֜ xwork 配置?/view 命名I间?
WebWork Portlet q需要你?web.xml 描述中徏立一些特D的 servlet ?filter 来打开?WebWork 标签库和模版语言的支? 因ؓ它依赖于一?Servlet API 的接口和c? 所以在WEB-INF 目录中创?web.xml 文g, q添加如下内?
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <filter> <filter-name>webwork</filter-name> <filter-class> com.opensymphony.webwork.dispatcher.FilterDispatcher </filter-class> </filter> <filter-mapping> <filter-name>webwork</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class> com.opensymphony.webwork.portlet.context.ServletContextHolderListener </listener-class> </listener> <servlet> <servlet-name>preparator</servlet-name> <servlet-class> com.opensymphony.webwork.portlet.context.PreparatorServlet </servlet-class> </servlet> <taglib> <taglib-uri>/webwork</taglib-uri> <taglib-location>/WEB-INF/lib/webwork-2.2.1.jar</taglib-location> </taglib> </web-app>
HttpServletRequest/Response, and other Servlet API classes in the ServletActionContext that is used in many of the JSPs and templates.
FilterDispacher 保证 webwork jar 包中的风格样式表?js 文g的URL可以被正解? ServletContextHolderListener 是一个Servlet context listener(上下文监听器), 它存放了 servlet context (上下? 的一个引? 在派?dispatch)到视?例如JSP/ftl或velocity)之前初始化包?HttpServletRequest/Response 和其它很多在JSP和模版引擎中会用到的ServletActionContext中的 Servlet API c?
With these basic project structure, portlet.xml and web.xml in place, it's time to do the mandatory "Hello World" example, so let's create a place to store our JSP files. Create a WEB-INF/pages/view folder, and within this folder, create the file "helloWorld.jsp". In this file, we simply put:
拥有了基本的目l构, portlet.xml ?web.xml 都有? 现在可以开始实?"Hello World" q个例子? 我们先徏立一个存?JSP 文g的目? 建立一?WEB-INF/pages/view 目录, 然后在这个目录里, 建立一?"helloWorld.jsp" 文g. 在这个文件中, 我们单写?
<H2>Hello world!</H2>
At this point, it's time to prepare the xwork configuration file, xwork.xml. Create an empty file named xwork.xml in the root of the 'src' folder. In this file we put:
Cq里, 是准?xwork 配置文g的时候了. 创徏一个叫?xwork.xml 的空文g, 攑֜ 'src' 的根目录?
在这个文件中, 我们攑֦下内?
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <include file="webwork-default.xml" /> <package name="view" extends="webwork-portlet-default" namespace="/view"> <action name="index" class="com.opensymphony.xwork.ActionSupport"> <result name="success">/WEB-INF/pages/view/helloWorld.jsp</result> </action> </package> </xwork>
q里要明一? 我们创徏了一个命名空间ؓ view 的包(package), 我们的包l承?webwork-portlet-default ? q个 webwork-portlet-default 包中包含了一些可以允许在 portlet 容器中运?WebWork/XWork 的特D结果类?result type).
除了常规?portlet.xml ?web.xml 表述文g, JBoss Portal 2.2 需要我们添加几?JBoss 的特定描q文? q些描述文g的名U将Ҏ我们的应用程序的上下文的?context root) 的名字来命名, 它一般也是我们导出的 war 包的名字. 我们E候将会创Z个叫?MyPortlet.war ?war ? 所?JBoss 描述文g被命名ؓ 'MyPortlet-object.xml'. 我们?WEB-INF目录中创个文? 然后d如下内容:
<?xml version="1.0" encoding="UTF-8"?> <deployments> <deployment> <if-exists>overwrite</if-exists> <parent-ref>default</parent-ref> <properties /> <page> <page-name>MyPortlet Tutorial</page-name> <properties /> <window> <window-name>MyPortletWindow</window-name> <instance-ref>MyPortletInstance</instance-ref> <region>center</region> <height>0</height> </window> </page> </deployment> <deployment> <if-exists>overwrite</if-exists> <instance> <instance-name>MyPortletInstance</instance-name> <component-ref>MyPortlet.MyPortlet</component-ref> </instance> </deployment> </deployments>
然后, 我们需要另外两个文? jboss-app.xml ?jboss-portlet.xml 它们内容如下:
<jboss-app> <app-name>MyPortlet</app-name> </jboss-app>
<portlet-app> <portlet> <portlet-name>MyPortlet</portlet-name> <security> </security> </portlet> </portlet-app>
现在我们的项目结构看h是这L:
目l构
现在可以试验一下我们的不可思议?HelloWorld portlet ? 在Windows的一个浏览器H口? 我们选择 WEB-INF 目录然后它?zip 格式压羃为叫?'MyPortlet.war' 的文? 这?war 文g攑ֈJBoss Portal?server/default/deploy 目录? 然后启动服务? 默认情况? JBoss Portal ?URL ?http://localhost:8080/portal, 所以我们用览器访问这个地址, 我们会看到q个 portal 的首? q里你应该会看到一?"MyPortlet Tutorial" 菜单? 与下面的截图中的一相同. 当按下菜单链? 你会得到一个奇妙的 "Hello World" 面!
JBoss Portal 首页
MyPortlet portlet 面
Next, let's do something a bit more interesting, namely create a simple form and display a result page. Let's start by creating our JSP that displays our form. Create a new file, 'helloForm.jsp' in the WEB-INF/pages/view/ folder. We will use the WebWork tag library to build the form on our page. The form itself will ask the user for a first name and last name, something like this:
接着, 我们来做一些有的? 也就是创Z个简单的 form q显CZ个结果页? 我们先来创徏一?JSP 面来显C?form. 创徏一个新的文?'helloForm.jsp', 攑֜ WEB-INF/pages/view/ 目录? 我们会使用 WebWork 标签库在我们的页面上创徏q个 form. q个 form 会询问用L名字和姓, 像q样:
<%@ taglib uri="/webwork" prefix="ww" %> <H2>Hi there! Please enter your name</H2> <ww:form action="helloWorld" method="POST"> <ww:textfield label="First name" name="firstName" value="%{firstName}"/> <ww:textfield label="Last name" name="lastName" value="%{lastName}"/> <ww:submit value="Say hello!"/> </ww:form>
现在我们准备写一?Java 代码, 不多, ׃点点. 我们在我们的 src 目录创徏一个新的包, 我们命名它ؓ com.opensymphony.webwork.portlet.tutorial. 在这个包? 创徏一?HelloWorldAction c? 遵@一般的 WebWork 习惯, q个cL展自XWork框架?ActionSupport c? 我们q会d一些属性来映射我们刚才创徏?JSP 中的 form 的属?
package com.opensymphony.webwork.portlet.tutorial; import com.opensymphony.xwork.ActionSupport; public class HelloWorldAction extends ActionSupport { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
We also need a JSP to display the processed input. We'll just use the old helloWorld.jsp and modify it a bit. As with helloForm.jsp, we import the WebWork tag library, and we use the ww:property tags to display the input from the form:
我们q需要一?JSP 来显C?input 的处理结? 我们q?helloWorld.jsp 然后修改一? ?helloForm.jsp 一? 我们引入 WebWork 标签? 然后我们使用 ww:property 标签来显C?form 中输入的内容:
<%@ taglib prefix="ww" uri="/webwork" %> <H2>Hello <ww:property value="firstName"/> <ww:property value="lastName"/></H2> <p/> <a xhref="<ww:url action="helloWorldInput"/>">Back to form</a>
现在我们准备好重新部|我们的应用E序, 所以重新用 zip 格式压羃好一?war 包ƈ攑ֈ server/default/deploy 目录. 现在 'MyPortlet Tutorial' 面会是这个样?
Hello World form
输入一些信? 然后点击 "Say hello!" 按钮, 然后你将会看C错的个性化?"hello" 信息:
个性化?Hello World
renderDirect(直接着?直接生成),实际上是把结果放到特定的WEB资源?.