??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲av无码乱码国产精品fc2,亚洲Av熟妇高潮30p,亚洲日本va一区二区三区http://www.tkk7.com/lendo/category/18174.htmlzh-cnWed, 28 Feb 2007 03:45:20 GMTWed, 28 Feb 2007 03:45:20 GMT60Webwork深入出 转自《开源大本营?作?钱安?2006-12-7)http://www.tkk7.com/lendo/articles/86060.htmllendolendoThu, 07 Dec 2006 03:58:00 GMThttp://www.tkk7.com/lendo/articles/86060.htmlhttp://www.tkk7.com/lendo/comments/86060.htmlhttp://www.tkk7.com/lendo/articles/86060.html#Feedback0http://www.tkk7.com/lendo/comments/commentRss/86060.htmlhttp://www.tkk7.com/lendo/services/trackbacks/86060.html 前言
本篇文章q没有太多WebWork 的实战代码细节。本人非常希望能充当一名导游的角色Q带领读者逐步游览WebWork的功能特性和原理。在W一章,我们提出基于三层架构的Web层需要解决的10个问题,q是本文的纵轴。围l着UuQ我们按照横轴的序逐步描述讲解QWebWork介、WebWork入门、WebWork原理、WebWork实战和技巧、展望WebWork未来、最后是本文的ȝ?/font>

Z三层架构?Web 层需要解决的问题
我们q里讨论的Web层,是基于典型的三层架构QWeb层,业务层,数据层。故Q我们将不讨ZQ何涉及业务(业务逻辑Q层和数据层功能的实现?/font>

Web层需要解决的问题Q?/font>

1?数据的输入。如何获得基于无状态HTTP的请求数据?如何请求的字符数据转换为对应的模型对象Q?/font>

2?输入数据的验证。如何验证输入数据的合法性ƈl出明确的错误消息提C?Q?

3?数据的输出。如何展现复杂的对象l构Q如何处理复杂的展现逻辑Q?

4?数据的传递和׃n。如何在不同的请求或面之间传递和׃n数据Q?

5?面的流E管理。如何管理Web应用中的面程Q?/font>

6?模块化的理。如何将复杂的Web应用以模块化的方式管理?

7?灉|可扩展的架构。如何支持各U不同的展现层技术?如何与业务层或数据层的各U框架整合?

8?安全和访问控制的理。如何提供基于Web的安全机制和资源讉K控制的管理?

9?代码实现的简z和高效。如何让开发步骤和代码l护变得单?如何量减少开发的中间环节Q如何将公共的功能剥d来,q可以灵zȝl装应用Q?

10?其它问题。异步调用、国际化支持、文件上传、防止重复提交等{?

下面Q让我们来一L看WebWork是如何解决上面的q些问题?/font>

WebWork ?

WebWork是由OpenSymphonyl织开发的Q致力于lg化和代码重用的J2EE Web框架。WebWork目前最新版本是2.2.2Q现在的WebWork2.x前n是Rickard Oberg开发的WebWorkQ但现在WebWork已经被拆分成了Xwork1和WebWork2两个目Q如下示意图所C:


workz、灵zd能强大,它是一个标准的Command模式框架实现Qƈ且完全从web层脱d来。Xwork提供了很多核心功能:前端拦截机(interceptorQ,q行时表单属性验证,cd转换Q强大的表达式语aQOGNL ?the Object Graph Notation LanguageQ,IoCQInversion of Control依赖倒{控制Q容器等?/font>

WebWork2建立在Xwork之上Q处理HTTP的请求和响应。所有的h都会被它的前端控制器QServletDispatcherQ最新版本是FilterDispatcherQ截莗前端控制器对请求的数据q行包装Q初始化上下文数据,Ҏ配置文g查找hURL对应的Actionc,执行ActionQ将执行l果转发到相应的展现面。WebWork2支持多视图表C,视图部分可以使用JSP, Velocity, FreeMarker, JasperReportsQXML{?/font>

下面我们提到的WebWorkؓWebWork2Q用的版本是WebWork2.2.2?/font>

WebWork 入门
WebWork 安装
如果只是搭徏一个WebWork开发环境,那将非常单:

1?ȝ站http://www.opensymphony.com/webwork下蝲最新的WebWork2.2.2目?/font>

2?搭徏一个Web应用Q这个不隑֐Q;q拷贝WebWork框架q行需要的所有Jar文g到Web应用的WEB-INF\lib中。这些Jar文gQ可以在WebWork目中lib\default目录扑ֈQ即那个目录里面的所有文件。当Ӟ别忘C天的“主角”,在WebWork跟目录下的webwork-2.2.2.jar文g?/font>

3?在Web.xml文g中配|WebWork的前端控制器FilterDispatcherQ也是一个普通的Servlet FilterQ过滤器Q而已。代码如下:

< 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 >

不过如果是在实际目中用,安装q程中还是有一些问题需要注意的Q?

1?关于前端控制器。在以前WebWork2版本里面Q前端控制器是ServeltDispatcherQ它是一个JavaServlet。而现在是一个Filter(qo?Q会D无法在页面中使用Jsp的include来包含一个WebWork的Actionh的URL。如果真的需要这样做Q可以用WebWork的action标签库?/font>

2?关于ActionhURL的后~。我们知道,在一般的Web框架中,前端控制器会特定后~的请求URL映射到对应的Actionh中。而我们这里的前端控制器会接受L的请求,但它默认是将.actionl尾的URL映射为WebWork的Actionh。我们可以在webwork.properties文g中,讄我们自己的后~名,多个后缀名可以用逗号隔开。例如:webwork.action.extension=action,do

3??Jsp 面中, WebWork 的标{ֺ不需要在 web.xml 中定义,在页面中通过如下的代码直接引用: <%@ taglib prefix = "ww" uri = "/webwork" %>

4?在Jsp面中,默认“altSyntax”是开启的。它是用来解x{ֺ中的字符串和表达式语ah的问题。所以,作ؓ变量的表辑ּ语言应该攑֜%{}中,否则WebWork会把它当作字W串处理?/font>

5?如果展现层技术用FreemarkerQWebWork官方的推荐,也是我个人的推荐Q,如果在页面中需要用标{ֺQ必dweb.xml中配|JspSupportServletQ代码如下:

< servlet >

< servlet-name > JspSupportServlet </ servlet-name >

< servlet-class > com.opensymphony.webwork.views.JspSupportServlet </ servlet-class >

< load-on-startup > 1 </ load-on-startup >

</ servlet >

6?q有一些其它的定制Q比如:~码Q标{模板文g{等Q都可以在webwork.properties文g中配|。如果在ClassPath中没有这个文ӞWebWork会自动读取WebWork的Jar包里面的default.properties文g?/font>

WebWork 核心概念
WebWork的三个关键部?/font>

1?Actions。一般一个Action代表一ơ请求或调用。在WebWork中,一般Actionc需要实现Action接口Q或者直接承基cActionSupport。这是,它要实现默认的executeҎQƈq回一个在配置文g中定义的ResultQ也是一个自定义的字W串而已Q。当ӞAction也可以只是一个POJOQ普通Java对象Q,不用l承McM不用实现M接口。Action是一ơ请求的控制器,同时也充当数据模型的角色Q我们强烈徏议不要将业务逻辑攑֜Action中?/font>

2?Results。它是一个结果页面的定义。它用来指示Action执行之后Q如何显C执行的l果。Result Type表示如何以及用哪U视图技术展现结果。通过Result TypeQWebWork可以方便的支持多U视图技术;而且q些视图技术可以互相切换,Action部分不需做Q何改动?/font>

3?Interceptors。WebWork的拦截器QWebWork截获ActionhQ在Action执行之前或之后调用拦截器Ҏ。这P可以用插拔的方式功能注入到Action中。WebWork框架的很多功能都是以拦截器的形式提供出来。例如:参数l装Q验证,国际化,文g上传{等?/font>

W一个例子: Welcome

入门Q我们从单的Welcome开始吧Q需求如下:一个页面,有一个用户名输入框;输入自己的名字,例如MoxieQ提交按钮返回一个欢q的面Qƈ昄前面输入的用户名和一句欢q信息,例如QMoxie, Welcome!面操作程囑֦下:


WelcomeAcion.java
welcomeResult.jsp
welcome.jsp

开发步骤如下:

1?输入面。Welcome.jsp是一个非常简单输入页面,代码如下Q?/font>

< form name = "register" action = "welcome.action" method = "POST" >

Name: < input name = "username" > Please input your name.

</ form >

2?WebWork的ActioncR它实现了Action接口Q获得welcome.jsp面传入的数据即输入的用户名Q根据这个用户名生成了一条欢q信息,q在l果面中打印出来。WelcomeAction.java代码如下Q?/font>

public class WelcomeAction implements Action{

private String username;

private String welcomeMessage;

public String execute() throws Exception {

welcomeMessage = username +",Welcome!";

return SUCCESS;

}

public void setUsername(String username) {

this.username = username;

}

public String getWelcomeMessage() {

return welcomeMessage;

}

}

看了上面的代码,也许你都不敢怿q就?Web ~程。没有调用Q何一?JavaServlet ?API Q它是如何获得请求的数据q将执行l果暴露l输入页面的呢?它是通过值堆栈和表达式语a来实玎ͼ后面会有详细介绍Q。我们先看看 Action 是如何获得请求的数据。输入框的名字?username ”,卌求的参数的名字,它就是一个表辑ּ语言?WebWork 遇到q个表达式语aQ就会执行相应的 setUsername ҎQ?username 参数的值就是执行这个方法的参数。这些是?Action 执行 execute Ҏ之前完成Q这?Action 可以获得请求的数据对象。类似的原理Q?WebWork 也是通过表达式语a?getWelcomeMessage Ҏ暴露l结果页面?

3?l果面。welcomeResult.jsp面Q将通过表达式语aQ取得Action执行之后暴露出来的数据对象。代码如下:

<%@ taglib prefix = "ww" uri = "/webwork" %>

< ww:property value = "%{welcomeMessage}" />

我们在结果页面中使用?WebWork 标签库。我们用到的?property 标签Q它通过表达式语aQ打?Action 暴露出的数据对象?

4?定义配置文gxwork.xml。代码如下:

< xwork >

< include file = "webwork-default.xml" />

< package name = "default" extends = "webwork-default" >

< action name = "welcome" class = "com.noname.web.action.WelcomeAction" >

< result name = "success" type = "dispatcher" > /welcomeResult.jsp </ result >

< interceptor-ref name = "params" />

</ action >

</package>

</xwork>

?name ”参数用于请求的 URL 。例如: http://localhost/welcome.action Q这样通过h?url Q我们就可以在配|文件中扑ֈ对应?action 。?class ”即实现 Action 的类。一?Action 中可以定义多?Result ?Result 的?name ”对?Action Ҏq回的字W串。在我们?WelcomeAction Ҏ中,执行成功之后q回字符东y?success ”。即我们在这?Action 里定义的那个 result 。?interceptor-ref ”定义这?action 所使用到的拦截器。我们这里用了 WebWork 提供?params 拦截器,它能自动的帮我们请求的参数l装?Action 中需要的数据对象。通过q个拦截器,它会调用 Action ?setUsername ҎQ取?username 参数的|q样 Action 可以获得用戯入的 username 数据。也怽会奇怪, params q个拦截器是从哪里变出来的?q个 xwork.xml 文g包含?WebWork 提供的默认配|文?webwork-default.xml,可以在webwork-2.2.2.jar文g中找到。我们定义的q个packagel承了它里面的package“webwork-default”,q样可以共享“webwork-default”package里面定义的所有拦截器?/font>

WebWork 原理
通过上面的例子,我们已经了解WebWork开发、运行的基本程Q一定要亲自安装Qƈ开发这个Welcome的例子哦Q。如果要在实际项目中使用WebWorkQ我们必要了解下面的概念和WebWork的原理?/font>

ValueStack( 值堆?) ?EL( 表达式语a )
关于ValueStack的描qͼ

1?ValueStack其实是一个放|Java对象的堆栈而已Q唯一特别的是可以使用EL来获得值堆栈中对象属性的数据Qƈ可以为值堆栈的对象属性赋倹{?/font>

2?ELQ全UExpress LanguageQ即表达式语a。不要被语言吓倒,它是单的对象D语言。有字符Ԍ例如Q方法名Q和Ҏ字符l成Q例如用.表示调用对应的属性方法)。通过ELQ我们可以存、取对象数据Q而且q可以直接访问类的静态数据,调用静态方法?/font>

3?WebWork的ValueStack底层有第三方开源项目OGNL实现。所以EL也都遵@OGNL的规范。我们在开发中Q几乎不需要知道OGNL的细节?/font>

4?WebWork为每一ơ请求构Z个ValueStackQƈ所有相关的数据对象Q例如:Action对象、Model对象{)攑ֈValueStack中。再ValueStack暴露l视N面,q样面可以直接访问后台处理生成的数据?/font>

下面我们用一个雇员类ZQ用Junit框架Q单元测试框Ӟ来展CValueStack的功能?/font>

我们有一个Employeec,它有两个属性:姓名Q地址。姓名是一个字W串Q地址是一个对象,地址cL国家、城市、街道三个属性。代码如下:

Employee.java代码如下Q?/font>

public class Employee {

private String name;

private Address address;

public Employee() {

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Address getAddress() {

if(address == null)

address = new Address();

return address;

}

public void setAddress(Address address) {

this.address = address;

}

}

Address.java代码如下Q?/font>

public class Address {

private String country;

private String city;

private String street;

…?/font>

//默认的Get和SetҎQ省?/font>

}

下面出场的是OgnlValueStackTestQ它有两个测试方法。分别测试用EL从ValueStack中取值和存倹{代码如下:

import com.opensymphony.xwork.util.OgnlValueStack;

import junit.framework.TestCase;

public class OgnlValueStackTest extends TestCase {

private OgnlValueStack valueStack;

private Employee employee;

@Override

protected void setUp() throws Exception {

valueStack = new OgnlValueStack();

employee = new Employee();

valueStack.push(employee);

}

public void testCouldGetDataFromObjectInOgnlValueStackByEL() throws Exception{

employee.setName("Moxie");

Address address = new Address();

address.setCountry("China");

employee.setAddress(address);

assertEquals("Moxie",valueStack.findValue("name"));

assertEquals("China",valueStack.findValue("address.country"));

}

public void testCouldSetDataForObjectInOgnlValueStackByEL() throws Exception{

valueStack.setValue("name","Moxie");

valueStack.setValue("address.country","China");

assertEquals("Moxie",employee.getName());

assertEquals("China",employee.getAddress().getCountry());

}

}

q是一个Junit TestQ关于Junit的用不是本文章的范畴。作Z个Java开发者,熟悉q样的测试框架是最基本的要求。setUpҎ在每个测试方法调用之前都会执行,它用来初始化每个试Ҏ都需要的对象和数据。我们的setUpҎ首先创徏两个对象QvalueStack对象和employee对象Q然后将employee对象入栈。这Pemloyee对象在值堆栈的最上端?/font>

W一个测试方法testCouldGetDataFromObjectInOgnlValueStackByEL试可以用表辑ּ语言取得值堆栈里的对象数据。我们首先ؓ值堆栈里的employee对象讄数据Q设|了用户名和用户地址所在的国家?/font>

W一个验证断a assertEquals("Moxie",valueStack.findValue("name"))解释为:我们期望使用表达式语a“name”去ValueStack中查扑־到的对象是”Moxie”。即期望valueStack.findValue("name")语句执行q回的数据是”Moxie”对象。再深入下去Q这条语句会调用ValueStack里对象的getNameҎQ即employee对象的getNameҎQ,q返回这个方法返回的数据?/font>

W二个断aassertEquals("China",valueStack.findValue("address.country"))。它期望表达式语a“address.country”取得的数据是对象的address属性对象的country属性,卛_得雇员对象的地址所在的国家。深入下去,它也是调用对象employee的getAddress().getCountry()Ҏ?W二个测试方法testCouldSetDataForObjectInOgnlValueStackByEL试通过表达式语a为ValueStack中的对象讄数据?/font>

W一个设D句valueStack.setValue("name","Moxie")Q它通过表达式语a“name”将“”Moxie””赋值给ValueStack里的对象Q即调用值堆栈中的对象的setNameҎQƈ把后面的g为方法的参数。同理,W二个设|语句会调用值堆栈中的对象的getAddress().setCountry()ҎQ把后面的数据作为setCountryҎ的参数?/font>

看了q个例子Q我们就会知道如何通过ValueStackq行数据的存取。在我们使用ValueStack旉要注意:

1?所有存取操作的目标对象都是已放入ValueStack中的对象。所以在使用之前Q必要先将对象入栈。例如我们在setupҎ中的语句QvalueStack.push(employee)?/font>

2?每一ơWebWorkhQ在创徏Action对象之前都会先生成一个ValueStack对象Q再Action对象入栈。这h们就可以通过表达式语a来直接存取action对象的数据,所以在WebWork中,actionh数据模型的功能?/font>

3?在对ValueStackq行存取操作Ӟ我们的操作指令(表达式语aQƈ不知道它是对哪个对象q行操作。例如,我们在获取员工姓名时Q我们给的操作指令是”name”,q时Qƈ不知道ValueStack里面的对象一定就是employee。ValueStack会从上而下Q遍历栈里面的对象,q试图调用当前遍历对象的getNameҎQ当它找Cq个ҎQƈ执行之后Q就会将执行得到的数据返回。这是那神U的ValueStack?/font>

4?关于值堆栈的context mapQ它是一个放|值堆栈上下文数据的对象。通过W号?“再加上对象的名Uͼ可以讉Kq些数据Q只可以讉KQ。一些JavaServlet相关的数据都攑֜q个容器中。这个对webwork的标{ֺ特别有用Q这h们可以直接通过表达式语a去访问request、attribute、session、application里的数据。例如:用property标签库打印出所有请求参数的数据Q代码如下:<ww:property value="%{#request}"/>?/font>

5?其它。“top”是ValueStack里面的关键字Q通过它可以找到ValueStack中最上面的那个对象。可以试着打印一下valueStack.findValue("top"))看看。表辑ּ语言除了可以调用ZJavaBean规范的get和setҎ之外Q还可以调用一般的JavaҎQ这是需要用方法的全名Qƈ传入需要的参数Q,也可以直接访问Javacȝ静态字D和静态方法。具体的使用Q可以查看WebWork的官Ҏ档?/font>

Interceptor( 拦截?)
拦截器在前面的“WebWork核心概念”章节做了简单介l,q里我们对它进行更q一步的探讨。关于拦截器的描qͼ

1?一个拦截器是在xwork.xml文g中定义的一个无状态Javac,它至要实现XWork的com.opensymphony.xwork.interceptor.Interceptor接口。代码如下:

public interface Interceptor extends Serializable {

void destroy();

void init();

String intercept(ActionInvocation invocation) throws Exception;

}

2?实现Interceptor接口的拦截器Q代码部分在interceptҎ中实现。在interceptҎ中,可以直接q回一个Result字符Ԍq样整个执行直接“短路”,q时Action的executeҎ也不会执行(一般很会q么用)。所以,一般都会在q个Ҏ里调用参数对象invocation的invokeҎQƈq回q个Ҏ执行的结果。这样会持箋执行后面的拦截器Ҏ以及Action的executeҎ{?/font>

3?大部分的时候,拦截器直接承WebWork的抽象类com.opensymphony.xwork.interceptor.AroundInterceptor可以了。这Ӟ需要实现它的before和afterҎ。BeforeҎ会在Action执行之前调用QafterҎ在Action执行之后调用?/font>

4?拦截器的执行序。我们可多个拦截器放一L装成一个拦截器栈。这h截器会按照栈的顺序由上而下执行beforeҎQ所有beforeҎ执行l束Q再执行Action的方法,执行Result的方法,再返回执行结果,最后再从下而上执行拦截器的afterҎ?/font>

5?拦截器的qo功能。我们通常会在应用中用一个通用的定义多个拦截器的拦截器栈。但有些ActionҎ在调用的时候,不需要要其中的部分拦截器。这Ӟ我们可以用拦截器qo功能。如果拦截器要拥有过滤功能,必须实现抽象ccom.opensymphony.xwork.interceptor.MethodFilterInterceptor。这P拦截器在定义的时候或者在Action引用拦截器栈的时候,我们可以指定哪些ActionҎ是需要过滤的Q哪些Action是不需要过滤的?/font>

WebWork提供的拦截器介绍

1?自动为Action讄Httph数据的拦截器(Parameters Interceptor)。这个拦截器非常方便实用Q但完全自动l装对象数据Q很可能会带来安全问题。如果Action不需要设|数据,那么q个Action只要实现com.opensymphony.xwork.interceptor.NoParameters接口卛_。如果是Action中部分数据需要自动设|,部分数据不允许设|,q样可以实现接口com.opensymphony.xwork.interceptor.ParameterNameAwareQ可以在q个接口的acceptableParameterName(String parameterName)Ҏ中,定义我们可以接受哪些ҎQ如果允许只要让q个Ҏq回True可以了?/font>

2?q虑参数功能的拦截器QParameter Filter InterceptorQ。它可以全局L非法或不允许Action讉K的参数。可以很好的和上面的l装参数的拦截器一起用?/font>

3?为Action讄静态数据的拦截器(Static Parameters InterceptorQ。它可以Action定义的静?lt;param/>参数Q设|到Action中?/font>

4?数据验证拦截器(Validation InterceptorQ。定义之后,会调用验证文件或实现验证接口com.opensymphony.xwork.Validateable的所有验证?/font>

5?验证程处理拦截器(Workflow InterceptorQ。它和上面的拦截器一起用,处理验证的流E。如果验证通过则l前q,如果发现有验证错误消息,直接转到Action中定义的输入l果QinputQ页面?/font>

6?cd转换错误处理拦截器(Q。它首先d得类型{换的错误消息Q主要是p|Httph参数的拦截器产生Q,如果取到错误消息Q它会将错误消息传递给实现接口com.opensymphony.xwork.ValidationAware的ActionQ这h们可以将q些错误消息暴露到页面中?/font>

7?Action链拦截器QChaining InterceptorQ。它是用来拷贝前一个Action的属性数据到当前Action中。它要求前一个Action必须是chain ResultQ?lt;result type="chain">Q,q样才能q行Action的数据拷贝?/font>

8?防止面重复提交Q或面重复hQ拦截器。Token Interceptor和Token Session Interceptor都是防止重复提交的拦截器。不同点是后者在Session存贮了最q一ơ请求的l果数据?/font>

9?文g上传的拦截器QFile Upload InterceptorQ。实现文件上传的功能。如果有人曾l手工写q文件上传程序,那一定会惊叹于这个拦截器。我们可以在q个拦截器中讑֮上传文g的大和cd限制。记得需要第三方的文件上传库的支持,只要在webwork.properties中配|过Qƈ拯相应的jar包就可以了?/font>

10?q度条等待拦截器QExecute and Wait InterceptorQ。当Action的执行需要很长实际的时候,我们可以使用q个q度条等待的拦截器。它会将Action攑ֈ后台执行Q而在前端昄q度条或{待消息提示的页面?/font>

11?q有一些其它不常用的拦截器Q我们可以在WebWork文档中找刎ͼq里׃再做介绍?/font>

IoC 容器
关于IoC容器的描qͼ

1?它是一个容器。用来处理不同对象之间的依赖Q组装不同的E序元素?

2?IoC全名是Inversion of ControlQ即依赖反{控制。它是一U设计模式,IoC容器是Zq个模式的实现?/font>

3?有一个比IoC更适合用来命名q一原理的名词,它叫Dependency InjectionQ即依赖注入?/font>

4?有了依赖注入Q我们可以将IoC容器单理解ؓQ它是一个用来ؓ对象l装其依赖的对象的容器;也就是说对象本n不用兛_它依赖的对象Q可以是lg或者服务,反正是提供业务Ҏ的对象)的创建,初始化,生命周期{,而是由容器来控制?/font>

5?关于IoC的更多信息可以查看Martin Fowler的经典文章《IoC 容器和Dependency Injection 模式?/font>

WebWork框架本n提供了一个基于接口的IoC容器。同时WebWork框架和提供了和第三方IoC容器的集成。在WebWork的项目中Q我们可以直接用Spring框架和Pico框架作ؓ自己的IoC容器。而且Spring是WebWork官方推荐的IoC容器?/font>

下面我们介l如何用Spring作ؓWebWork的IoC容器。在讨论如何集成Spring之前Q我们要讨论一个非常有意义的架构问题:

WebWork的ActioncL否需要由Spring理Q?/font>

1?否。这样Actionc还是象以前那样在xwork文g中定义,我们可以通过标签<external-ref/>定义Action所依赖的BeanlgQ或者根据Bean的名字或cdq行自动注入?/font>

2?是。ActioncLw也是有Spring来管理。在xwork定义文g中的Action class是对Bean的引用,具体的类在Spring的Bean配置文g中定义。这样可以更好的使用Sping为我们提供的更多功能Q例如:Spring的复杂AOP功能Q基于Acegi的权限控Ӟ{等?/font>

两种ҎQ根据需要选择一U,我个人更們֐后者。下面我们介l一下Spring容器的安装步骤:

1?拯Spring依赖的所有jar文g

2?在web.xml文g定义和开启Spring的监听器Q代码如下:

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

3?在webwork.properties中设|WebWork对Spring的支持:webwork.objectFactory = spring

4?可以在webwork.properties中设|Beanlg的默认组装方式,默认是按照Bean的名Uͼ可以选择按照cd、构造函数、自动选择{方式?/font>

WebWork 原理


WebWork的网站上提供了一个完整的WebWork架构图。它描述了从客户端的一ơ请求到最后服务器端响应的的整个执行过E。架构图如下Q?/font>

此架构图一个分Z个部分,其中五个部分分别有五中不同颜色表C?

1?灰色方框。分别代表了客户端的一ơHttphQ和服务器端q算l束之后的一ơ响应?/font>

2?红色方框。表CZơActionh所要经q的Servlet filtersQServlet qo器)。我们可以看到最后一个filter是我们前面介绍的WebWork的前端控制器?/font>

3?蓝色Ҏ。这是WebWork框架的核心部分?/font>

1Q?一ơ请求到了WebWork的前端控制器Q它首先会根据请求的URL解析出对应的action 名称Q然后去咨询ActionMapperq个action是否需要被执行?/font>

2Q?如果ActionMapper军_q个action需要被执行Q前端控制器把工作委派lActionProxy。接着她们会咨询WebWork的配|管理器Qƈd在web.xml文g中定义的配置信息。接下来ActionProxy会创建ActionInvocation对象?/font>

3Q?ActionInvocation是Xwork原理的(Command模式Q实现部分。它会调用这个Action已定义的拦截?beforeҎ)QActionҎQResultҎ?/font>

4Q?最后,看上面流E的囄方向Q它会再执行拦截器(afterҎQ,再回到Servlet Filter部分Q最后结束ƈ传给用户一个结果响应?/font>

4?靛色Ҏ。这是拦截器部分Q在上面的拦截器章节我们已经有了详细的介l?

5?黄色Ҏ。这是我们在开发Web应用Ӟ需要自己开发的E序。其中包括:Actionc,面模板Q配|文件xwork.xml?/font>

WebWork 实战和技?
限于幅Q我们无法在本章节给出很多详的具体实例。其实,在WebWork的代码包中,有一个非常好的演C项目——showcaseQ它用例子演CZWebWork的几乎所有特性。值得初学的朋友反复研I。我们在本章节中会截取其中的部分代码脚本?/font>

1?多视图支持。WebWork框架天生支持多种视图技术,包括QJsp、FreeMarker、Velocity、Jasper Reports、XSLTQ还有其它的视图技术。这在敏捷目中特别有用。在我咨询的目中,有一个因为技术的原因Q视图技术由最先的Jsp改ؓVelocityQ后来又攚wؓFreeMarker。其中,ActioncM及后台的E序没有做Q何的改动。如果您需要一个视囑ֱ现层技术,我在q会好不犹U的向您推荐FreeMarker。这也是官方的推荐?/font>

关于视图技术的使用Q首先是搭徏视图技术运行的环境。然后就是编写页面脚本,最后就是在xwork.xml文g中配|。Xwork配置文g中,Result的type参数Q就是用来标C所使用的视图技术。在showcase目中,使用到的视图技术有QJsp、FreeMarker、Velocity、Jasper Reports?/font>

2?Action的数据验证功能。在WebWork中,可以在三处实现数据验证功能。一、验证文Ӟ例如:ActionClass-validation.xml文gQ中定义数据验证规则。二、在Action中实现com.opensymphony.xwork.Validateable接口的validateҎ。三、在Action的执行方法中Q硬~码实现验证功能。当Ӟ在实现验证时Q我们尽可能的用前面两中Ҏ?/font>

关于验证的说明:

1Q、第一U验证需要“validation”拦截器的支持。ƈ可以从Q意层ơ绑定验证文Ӟ可以Z个Actioncȝ定一个验证文Ӟ也可以ؓ一个具体在xwork.xml文g中的Action定义l定一个验证文Ӟ可以为Action的一个属性对象绑定一个验证文Ӟ甚至可以为Action的父cȝ定验证文件?/font>

2Q、WebWork为验证文件提供了一些标准的验证实现:例如Q字D必d写,整型、E-mail地址{等。我们也可以使用表达式语a实现更复杂的数据验证?/font>

3?cd转换。前面外面一直提到过QWebWork会自动从h的字W串参数中组装Action需要的数据对象。这P׃存在一个类型{换的问题。如果Action的字D|基本cd或是一个数据对象,WebWork会自动帮我们处理。如果Action的字D|一个集合,或者我们需要特定的cd转换Q这Ӟ我们可以在类型{换的定义文gQClassName-conversion.propertiesQ中定义转换规则?/font>

4?一个Action的多个执行方法。WebWork的Action是基于Command模式的实玎ͼ在WebWork中,除了实现Action接口的execute()Ҏ之外QActionq可以定义多个执行方法。这些方法必要是无Ҏ参数Qƈ且返回返回字W串的方法。这h们在Url中可以用cM下面的格式访问:actionName!methodName.actionQ例如user!doAdd.actionQ调用user ActioncȝdoAddҎ。在最新的WebWork中,Actioncȝ臛_以不实现Action接口?/font>

5?Action链(Action ChainingQ。在WebWork中,一ơ用戯求,可由多个Action共同完成。每个Action可以只实现自己本w的功能单元Q这h们可以根据业务需要ؓ用户的一ơ请求选择一个或多个Action功能单元来实现。在q样的多个Action之间可以通过chain拦截器共享数据。如果请求由Action x 铑ֈAction yQ如果这时y需要获得x的数据,我们需要ؓAction ydchain拦截器?/font>

例如Q在showcase中就由Action Chaining的应用。它Action“actionChain2”链到另外一个Action“actionChain3”,配置文g代码如下Q?/font>

< action name = "actionChain2" class = "com.opensymphony.webwork.showcase.actionchaining.ActionChain2" >

< result type = "chain" > actionChain3 </ result >

</ action >

< action name = "actionChain3" class = "com.opensymphony.webwork.showcase.actionchaining.ActionChain3" >

< result > /actionchaining/actionChainingResult.jsp </ result >

</ action >

注意Q如果要?chain 拦截器,是需要加?actionChain3 中,而不?actionChain2 ?

6?多模块支持解x案?WebWork 提供了很灉|的多模块解决ҎQ这h们可以很好的l织复杂?Web 应用目?

1 Q可以在 xwork.xml 文g中,?include 标签包含另外的一?xwork 配置文g。例如: <include file="webwork-default.xml"/>

2 Q?xwork.xml 配置文g支持 package 。我们可以将一个业务模块的定义方到一?package Q?package 支持l承功能Q子 package 可以享有?package 的所有定义?

3 Q可以ؓ package 定义一个命名空间。不同的命名I间可以定义相同?action 名字。命名空间会用于讉K action ?URL Q基于这个命名空_我们可以实现资源权限的访问控制?

7?doInput Ҏ。这是我们常用的技巧,有时候请求的是一个页面模板,M能ؓq个单独写一?Action cdQ这时我们就可以?ActionSupport ?doInput ҎQ直接返回在 Actoion 中定义ؓ?input ”的 result ?

8?prepareҎ。如果在Action执行之前Q必要初始化一些数据。我们可以将q些初始化的代码方到prepareҎ中。这ӞActionc要实现接口com.opensymphony.xwork.PreparableQ同时这个Action的定义还需要PrepareInterceptor拦截器的支持?/font>

9?Action的Model Driven。我们大部分的时候用得都是Action的Field DrivenQ即直接Action的字D作为数据模型。Model Driven是专门ؓq个Action指定一个模型对象,q样有什么好处呢Q好处是在表辑ּ语言中少了一个对象名的前~。例如:前面值堆栈部分关于Employee的例子,要设|雇员名Uͼ我们必须要表辑ּ语言例如Q“employee.name”,如果q个数据是有面输入得到Q那么你必L一个Input输入框的name为“employee.name”,因ؓ它有关键字符?”,如果Javascript脚本使用q个输入框的名字Q就会有错误。用Model Driven之后Q这个表辑ּ可以变为“name”,省去了前面的“employee.”?/font>

10?Quick Start。这是WebWork2.2.2中非常激动h心的Ҏ。它可以象perl或PHP可以快速看到程序运行结果。这样在Web开发时Q可以不用编译Java源代码,也不用去做打包和部vQ就可以快速看到最新程序的q行l果Q提高开发效率。我们可以在WebWork源码解压包的根目录,输入命oQjava -jar webwork-2.2.2.jar quickstart:showcaseQ需要jdk1.5的支持)Q以Quick Start模式Q运行showcase目?/font>

展望 WebWork 未来
q是很多人非常关心的一个问题。特别是WebWork2.2版本发布之后Q官方宣UWebWork框架要和Struts合ƈ。这让一些WebWork的用户生了担忧Q合q之后,是不是就意味着自己在WebWorkq方面技术和l验的积累都已浪费?已用或卛_使用WebWork的项目是不是意味着更多的风险?

{案是:完全不用担心q些。WebWork和Struts的合qӞ是各取所长,然后诞生Z个更加高效的Web框架。而这个框架用得就是WebWork的优U技术和Struts的强大社区?/font>

合ƈ的情况如下:

1?产生一个新的项目Struts Action 2.0 = WebWork2.2 + 一些Struts的功能和Ҏ?/font>

2?WebWork框架会中止新功能的增加Q如果有新的版本发布都会是Bug的修攏V?/font>

3?代码、框架的开发者、社区都移到Struts?/font>

4?合ƈ的目标是致力于生产率的提高?

5?Struts不再是一个框Ӟ它是一个社区?/font>

6?StrutsC֌中主要有两个Web框架。一个是ZAction模型的Struts ActionQ另一个是Zlg模型的Struts Shale?/font>

ȝ

WebWork是本人工L中最q一个J2EE Web框架。本人开发过单纯使用Jsp和JavaServlet的项目;也曾l自己开发过ZMVC的Web框架Q在2002q开始用Struts开发;后来也在目中分别用过Tapestry和Spring MVC Web框架Q也在当今的AJAX潮流中随波逐流。上面的一些技术也都非怼UQ擅用他们Q何一个都会给您带来很多生产效率的提高。但我仍然是偏爱WebWork。WebWork的与众不同,得力于它ZOGNL的强大的数据存、取方式Q得力于它那解耦的拦截器功能,得力于它那无侵入的架构设计。正是由于它Q才让Web~程变得更加的自然、简单、灵zR高效?/font>



lendo 2006-12-07 11:58 发表评论
]]>
使用webwork标签(2006-12-7)http://www.tkk7.com/lendo/articles/86058.htmllendolendoThu, 07 Dec 2006 03:54:00 GMThttp://www.tkk7.com/lendo/articles/86058.htmlhttp://www.tkk7.com/lendo/comments/86058.htmlhttp://www.tkk7.com/lendo/articles/86058.html#Feedback0http://www.tkk7.com/lendo/comments/commentRss/86058.htmlhttp://www.tkk7.com/lendo/services/trackbacks/86058.html webwork中,从action向前端展?如:jsp)传参数时Q可以用:
    . application.setAttribute("point",Object);
    . session.setAttribute("point",Object);
    . request.setAttribute("point",Object);
    在前端可以用对应?
    ${applicationScope.point}
    ${sessionScope.point}
    ${requestScope.point}
    来对D行访问?/font>

     但是Q在从前端向action传值的时候,如果值都是通过form来传值的Q那么action里面只能通过request.getParemeter()来取得前端的|我今天犯了个错误,在action里面也通过request.getAttribute()来取得前端的|l果始终是空NullPointerQ如果想通过request.getAttribute()来取得前端的值就必须在前端通过request.setAttribute()Ҏ来设|了才能在action中进行访问?br />     所谓变量的生存周期是指通过setAttribute()Ҏ讄的值的生存周期Q而不是通过form来提交数据的生存周期?/font>



lendo 2006-12-07 11:54 发表评论
]]>
վ֩ģ壺 ޵һӰԺ| ޾Ʒþþþϼ | ѵӰվ| | ޸Ƶ| selaobanƵѾƷ| ˾ƷƵ| ޳վ| aɫëƬƵ| ҹ޸˾| ޹Ʒþҹ| ר˿ŵƵ| ޹˾þۺһ| ɫѹۿ| ձ| ɫ˵| վѹۿ| þAAAƬ69| þù׾Ʒǿ| Ƭһһ߹ۿ | ˮһ| ޸Ƶ| ޼Ļ| һ߹ۿ| Ļ߹ۿձ| èԴ߹ۿ| Ƶۿ| רþ| Ļձ޾þþ| ޾ƷҹVAþó| aëƬѹۿվ| ɫͼ߹ۿ| պaëƬѹۿ| þøݾƷԴվ| mate20pro鶹| ޾Ʒ| ĻƬ| ޵һƵ߹ۿ| 99ƵƷѹۿ7| ޹˱ɫ߹ۿ| ˿Ƶ2019|