webwork框架例子.docx
- 文档编号:2848293
- 上传时间:2023-05-04
- 格式:DOCX
- 页数:14
- 大小:24.89KB
webwork框架例子.docx
《webwork框架例子.docx》由会员分享,可在线阅读,更多相关《webwork框架例子.docx(14页珍藏版)》请在冰点文库上搜索。
webwork框架例子
webwork框架例子
【篇一:
webwork框架例子】
在中,我简单的介绍了我们分层开发中每一层中拥有的框架,而且介绍了我常用的,那么今天我继续介绍我熟悉的框架struts2的框架的结构和原理分析。
在说struts2框架之前,我要先介绍另外一个框架webwork框架,这个框架也是一个mvc的框架,这个框架的设计思路是采用拦截链将用户的请求的数据转发到action中,并负责将action的处理结果转换成对用户的响应。
它的这种设计思路能够和servletapi分离,鉴于我们的上篇博客介绍的struts1的缺点,所以webwork框架解决了struts1的这个缺点。
我们来看一下webwork框架的结构图:
有了这个流程图,我就不给大家讲解具体的原理流程了,它采用的是拦截链的机制,通过这些拦截链完成用户的相应请求,从而与servletapi分离,当与servlet分离开的时候,也就是表明和容器解耦了;另外,我们从结构图中看到它的视图模版有jsp、freemarker等等,它的表示层技术比struts1框架的饱满许多。
所以,webwork框架解决了struts1框架存在的问题,而且它的设计思路是非常好的,鉴于此,struts2框架就在struts1框架的基础上引入了webwork框架的设计思路应运而生了。
所以我们就能够发现struts2兼具struts1的特性而且通过引入webwork框架的设计思路解决了struts1的一些缺点。
struts2框架的大致的体系图:
从图中我们能够看出它是引入的webwork框架的设计思路,而且它也是基于mvc的一个开源的框架。
之后我们来说一下struts2框架的一个执行流程(流程图和webwork框架非常类似):
浏览器发送请求,通过几层过滤器完成一些功能,之后到actionmapper中,之后将请求传到核心控制器中核心控制器filterdispatcher根据请求决定调用合适的action调用webwork的拦截器链自动请求通用功能,如校验之类的操作回调action的execute方法,获取用户请求执行相应的业务逻辑之后返回字符串,匹配result,之后跳转到相应的视图或其他的文档之后在执行相应的拦截器链自动请求功能,随后转到web客户端。
这样我们就对struts2框架的结构上的东西做了一个简单的介绍。
在上篇博客讲解了struts1框架,所以有必要在这里对他俩进行一下对比(我仅仅总结了五条我认为比较重要的,以后如果发现其他的在随时补充):
在action实现类方面的对比(struts1的action继承action,struts2实现接口,也可以不实现,可以定制服务)线程模式方面的对比(struts1存在线程安全问题,struts2不存在)servletapi依赖方面的对比(struts1依赖servletapi,struts2不是)可测性方面的对比(struts1难测试,依赖容器,struts2不是)封装请求参数的对比(struts1使用actionform;struts2直接写到action,并且支持pojo对象)
这篇博客就介绍到这里,宏观上的学习以前一直做的不好,所以这段时间一直在解决这个学习上出现的问题,希望我的这些重构的框架学习博客能够对大家有所帮助。
下节课我会继续介绍我经常使用的框架的结构和执行流程的分析,敬请关注!
【篇二:
webwork框架例子】
下面出场的是ognlvaluestacktest,它有两个测试方法。
分别测试使用el从valuestack中取值和存值。
代码如下:
importcom.opensymphony.xwork.util.ognlvaluestack;
importjunit.framework.testcase;
publicclassognlvaluestacktestextendstestcase{
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
privateognlvaluestackvaluestack;
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
privateemployeeemployee;
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
override
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
protectedvoidsetup()throwsexception{
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
valuestack=newognlvaluestack();
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
employee=newemployee();
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
valuestack.push(employee);
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
}
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
publicvoidtestcouldgetdatafromobjectinognlvaluestackbyel()throwsexception{
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
employee.setname(moxie);
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
addressaddress=newaddress();
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
address.setcountry(china);
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
employee.setaddress(address);
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
assertequals(moxie,valuestack.findvalue(name));
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
assertequals(china,valuestack.findvalue(address.country));
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
}
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
publicvoidtestcouldsetdataforobjectinognlvaluestackbyel()throwsexception{
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
valuestack.setvalue(name,moxie);
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
valuestack.setvalue(address.country,china);
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
assertequals(moxie,employee.getname());
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
assertequals(china,employee.getaddress().getcountry());
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
}
}
这是一个junittest,关于junit的使用不是本篇文章的范畴。
作为一个java开发者,熟悉这样的测试框架是最基本的要求。
setup方法在每个测试方法调用之前都会执行,它用来初始化每个测试方法都需要的对象和数据。
我们的setup方法首先创建两个对象:
valuestack对象和employee对象,然后将employee对象入栈。
这样,emloyee对象就在值堆栈的最上端。
第一个测试方法testcouldgetdatafromobjectinognlvaluestackbyel测试可以用表达式语言取得值堆栈里的对象数据。
我们首先为值堆栈里的employee对象设置数据,设置了用户名和用户地址所在的国家。
第一个验证断言?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
assertequals(moxie,valuestack.findvalue(name))解释为:
我们期望使用表达式语言“name”去valuestack中查找得到的对象是”moxie”。
即期望valuestack.findvalue(name)语句执行返回的数据是”moxie”对象。
再深入下去,这条语句会调用valuestack里对象的getname方法(即employee对象的getname方法),并返回这个方法返回的数据。
第二个断言assertequals(china,valuestack.findvalue(address.country))。
它期望表达式语言“address.country”取得的数据是对象的address属性对象的country属性,即取得雇员对象的地址所在的国家。
深入下去,它也就是调用对象employee的getaddress().getcountry()方法。
?
?
第二个测试方法testcouldsetdataforobjectinognlvaluestackbyel测试通过表达式语言为valuestack中的对象设置数据。
第一个设值语句valuestack.setvalue(name,moxie),它通过表达式语言“name”将“”moxie””赋值给valuestack里的对象,即调用值堆栈中的对象的setname方法,并把后面的值作为方法的参数。
同理,第二个设置语句会调用值堆栈中的对象的getaddress().setcountry()方法,把后面的数据作为setcountry方法的参数。
看了这个例子,我们就会知道如何通过valuestack进行数据的存取。
在我们使用valuestack时需要注意:
1、?
?
所有存取操作的目标对象都是已放入valuestack中的对象。
所以在使用之前,必须要先将对象入栈。
例如我们在setup方法中的语句:
valuestack.push(employee)。
2、?
?
每一次webwork请求,在创建action对象之前都会先生成一个valuestack对象,再将action对象入栈。
这样我们就可以通过表达式语言来直接存取action对象的数据,所以在webwork中,action具有数据模型的功能。
3、?
?
在对valuestack进行存取操作时,我们的操作指令(表达式语言)并不知道它是对哪个对象进行操作。
例如,我们在获取员工姓名时,我们给的操作指令是”name”,这时,并不知道valuestack里面的对象一定就是employee。
valuestack会从上而下,遍历栈里面的对象,并试图调用当前遍历对象的getname方法,当它找到了这个方法,并执行之后,就会将执行得到的数据返回。
这就是那神秘的valuestack。
5、?
?
其它。
“top”是valuestack里面的关键字,通过它可以找到valuestack中最上面的那个对象。
可以试着打印一下valuestack.findvalue(top))看看。
表达式语言除了可以调用基于javabean规范的get和set方法之外,还可以调用一般的java方法(这是需要使用方法的全名,并传入需要的参数),也可以直接访问java类的静态字段和静态方法。
具体的使用,可以查看webwork的官方文档。
interceptor(拦截器在前面的“webwork核心概念”章节做了简单介绍,这里我们将对它进行更进一步的探讨。
关于拦截器的描述:
1、?
?
一个拦截器就是在xwork.xml文件中定义的一个无状态java类,它至少要实现xwork的com.opensymphony.xwork.interceptor.interceptor接口。
代码如下:
publicinterfaceinterceptorextendsserializable{
?
?
?
?
?
?
voiddestroy();
?
?
?
?
?
?
voidinit();
?
?
?
?
?
?
stringintercept(actioninvocationinvocation)throwsexception;
}
2、?
?
实现interceptor接口的拦截器,代码部分在intercept方法中实现。
在intercept方法中,可以直接返回一个result字符串,这样整个执行直接“短路”,这时action的execute方法也不会执行(一般很少会这么用)。
所以,一般都会在这个方法里调用参数对象invocation的invoke方法,并返回这个方法执行的结果。
这样会持续执行后面的拦截器方法以及action的execute方法等。
3、?
?
大部分的时候,拦截器直接继承webwork的抽象类com.opensymphony.xwork.interceptor.aroundinterceptor就可以了。
这时,需要实现它的before和after方法。
before方法会在action执行之前调用,after方法在action执行之后调用。
4、?
?
拦截器的执行顺序。
我们可将多个拦截器放一起组装成一个拦截器栈。
这样拦截器会按照栈的顺序由上而下执行before方法,所有before方法执行结束,再执行action的方法,执行result的方法,再返回执行结果,最后再从下而上执行拦截器的after方法。
5、?
?
拦截器的过滤功能。
我们通常会在应用中使用一个通用的定义多个拦截器的拦截器栈。
但有些action方法在调用的时候,不需要要其中的部分拦截器。
这时,我们就可以使用拦截器过滤功能。
如果拦截器要拥有过滤功能,必须实现抽象类com.opensymphony.xwork.interceptor.methodfilterinterceptor。
这样,拦截器在定义的时候或者在action引用拦截器栈的时候,我们就可以指定哪些action方法是需要过滤的,哪些action是不需要过滤的。
webwork提供的拦截器介绍
1、?
?
自动为action设置http请求数据的拦截器(parametersinterceptor)。
这个拦截器非常方便实用,但完全自动组装对象数据,很可能会带来安全问题。
如果action不需要设置数据,那么这个action只要实现com.opensymphony.xwork.interceptor.noparameters接口即可。
如果是action中部分数据需要自动设置,部分数据不允许设置,这样可以实现接口com.opensymphony.xwork.interceptor.parameternameaware,可以在这个接口的acceptableparametername(stringparametername)方法中,定义我们可以接受哪些方法,如果允许只要让这个方法返回true就可以了。
2、?
?
过虑参数功能的拦截器(parameterfilterinterceptor)。
它可以全局阻止非法或不允许action访问的参数。
可以很好的和上面的组装参数的拦截器一起使用。
3、?
?
为action设置静态数据的拦截器(staticparametersinterceptor)。
它可以将action定义的静态param/参数,设置到action中。
4、?
?
数据验证拦截器(validationinterceptor)。
定义之后,会调用验证文件或实现验证接口com.opensymphony.xwork.validateable的所有验证。
5、?
?
验证流程处理拦截器(workflowinterceptor)。
它和上面的拦截器一起使用,处理验证的流程。
如果验证通过则继续前进,如果发现有验证错误消息,直接转到action中定义的输入结果(input)页面。
6、?
?
类型转换错误处理拦截器()。
它首先去取得类型转换的错误消息(主要是由设置http请求参数的拦截器产生),如果取到错误消息,它会将错误消息传递给实现接口com.opensymphony.xwork.validationaware的action,这样我们可以将这些错误消息暴露到页面中。
7、?
?
action链拦截器(chaininginterceptor)。
它是用来拷贝前一个action的属性数据到当前action中。
它要求前一个action必须是chainresult(resulttype=chain),这样才能进行action的数据拷贝。
8、?
?
防止页面重复提交(或页面重复刷新)拦截器。
tokeninterceptor和tokensessioninterceptor都是防止重复提交的拦截器。
不同点是后者在session存贮了最近一次请求的结果数据。
9、?
?
文件上传的拦截器(fileuploadinterceptor)。
实现文件上传的功能。
如果有人曾经手工写过文件上传程序,那一定会惊叹于这个拦截器。
我们可以在这个拦截器中设定上传文件的大小和类型限制。
记得需要第三方的文件上传库的支持,只要在webwork.properties中配置过,并拷贝相应的jar包就可以了。
10、?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
进度条等待拦截器(executeandwaitinterceptor)。
当action的执行需要很长实际的时候,我们可以使用这个进度条等待的拦截器。
它会将action放到后台执行,而在前端显示进度条或等待消息提示的页面。
11、?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
还有一些其它不常用的拦截器,我们可以在webwork文档中找到,这里就不再做介绍。
关于ioc容器的描述:
1、?
?
它是一个容器。
用来处理不同对象之间的依赖,组装不同的程序元素。
2、?
?
ioc全名是inversionofcontrol,即依赖反转控制。
它是一种设计模式,ioc容器就是基于这个模式的实现。
3、?
?
有一个比ioc更适合用来命名这一原理的名词,它叫dependencyinjection,即依赖注入。
4、?
?
有了依赖注入,我们可以将ioc容器简单理解为:
它是一个用来为对象组装其依赖的对象的容器;也就是说对象本身不用关心它依赖的对象(可以是组件或者服务,反正就是提供业务方法的对象)的创建,初始化,生命周期等,而是由容器来控制。
5、?
?
关于ioc的更多信息可以查看martinfowler的经典文章《ioc容器和dependencyinjection模式》
webwork框架本身就提供了一个基于接口的ioc容器。
同时webwork框架和提供了和第三方ioc容器的集成。
在webwork的项目中,我们可以直接使用spring框架和pico框架作为自己的ioc容器。
而且spring是webwork官方推荐的ioc容器。
下面我们将介绍如何使用spring作为webwork的ioc容器。
在讨论如何集成spring之前,我们要讨论一个非常有意义的架构问题:
webwork的action类是否需要由spring管理?
1、?
?
否。
这样action类还是象以前那样在xwork文件中定义,我们可以通过标签external-ref/定义action所依赖的bean组件,或者根据bean的名字或类型进行自动注入。
2、?
?
是。
action类本身也是有spring来管理。
在xwork定义文件中的actionclass就是对bean的引用,具体的类在spring的bean配置文件中定义。
这样可以更好的使用sping为我们提供的更多功能,例如:
spring的复杂aop功能,基于acegi的权限控制,等等。
两种方法,根据需要选择一种,我个人更倾向后者。
下面我们介绍一下spring容器的安装步骤:
1、?
?
拷贝spring依赖的所有jar文件
2、?
?
在web.xml文件定义和开启spring的监听器,代码如下:
listener
?
?
?
?
?
?
?
?
listener-classorg.springframework.web.context.contextloaderlistener/listener-class
?
?
?
?
?
?
?
?
?
?
/listener
3、?
?
在webwork.properties中设置webwork对spring的支持:
webwork.objectfactory=spring
4、?
?
可以在webwork.properties中设置bean组件的默认组装方式,默认是按照bean的名称,可以选择按照类型、构造函数、自动选择等方式。
webwork
webwork的网站上提供了一个完整的webwork架构图。
它描述了从客户端的一次请求到最后服务器端响应的的整个执行过程。
架构图如下:
【篇三:
webwork框架例子】
基于三层架构的web层需要解决的问题
我们这里讨论的web层,是基于典型的三层架构:
web层,业务层,数据层。
故,我们将不讨论任何涉及业务(业务逻辑)层和数据层功能的实现。
web层需要解决的问题:
1、数据的输入。
如何获得基于无状态http的请求数据?
如何将请求的字符数据转换为对应的模型对象?
2、输入数据的验证。
如何验证输入数据的合法性并给出明确的错误消息提示?
3、数据的输出。
如何展现复杂的对象结构?
如何处理复杂的展现逻辑?
4、数据的传递和共享。
如何在不同的请求或页面之间传递和共享数据?
5、页面的流程管理。
如何管理web应用中的页面流程?
6、模块化的管理。
如何将复杂的web应用以模块化的方式管理?
7、灵活可扩展的架构。
如何支持各种不同的展现层技术?
如何与业务层或数据层的各种框架整合?
8、安全和访问控制的管理。
如何提供基于web的安全机制和资源访问控制的管理?
9、代码实现的简洁和高效。
如何让开发步骤和代码维护变得简单?
如何尽量减少开发的中间环节?
如何将公共的功能剥离出来,并可以灵活的组装应用?
10、其它问题。
异步调用、国际化支持、文件上传、防止重复提交等等。
下面,让我们来一起看看webwork是如何解决上面的这些问题。
webwork框架简介
webwork框架是由opensymphony组织开发的,致力于组件化和代码重用的j2eeweb框架。
webwork目前最新版本是2.2.2,现在的webwork2.x前身是rickardoberg开发的webwork,但现在webwork已经被拆分成了xwork1和webwork2两个项目,如下示意图所示:
work简洁、灵活功能强大,它是一个标准的command模式框架实现,并且完全从web层脱离出来。
xwork提供了很多核心功能:
前端拦截机(interceptor),运行时表单属性验证
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- webwork 框架 例子