Webx框架:http://openwebx.org/
Webx MVC(以webx3为基础)
1、webx3的入口点
<filter> <filter-name>webx</filter-name> <filter-class>com.alibaba.citrus.webx.servlet.WebxFrameworkFilter</filter-class> </filter> <filter-mapping> <filter-name>webx</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
webx.xml:每个webx应用,都需要有一个webx.xml配置文件。这个文件定义了Webx所用到的所有services的配置。
pipeline.xml:即管道,它是由一个或多个“阀门Valve”构成的。可以看做webx框架的总控文件。
log4j.xml:日志系统配置文件。对于程序的排错至关重要。
典型的webx.xml配置:
<?xml version="1.0" encoding="UTF-8" ?> <!-- Webx Root Context Configuration. --> <beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:services="http://www.alibaba.com/schema/services" xmlns:request-contexts="http://www.alibaba.com/schema/services/request-contexts" xmlns:session-encoders="http://www.alibaba.com/schema/services/request-contexts/session/encoders" xmlns:model-encoders="http://www.alibaba.com/schema/services/request-contexts/session/model-encoders" xmlns:session-idgens="http://www.alibaba.com/schema/services/request-contexts/session/idgens" xmlns:session-stores="http://www.alibaba.com/schema/services/request-contexts/session/stores" xmlns:ml-adapters="http://www.alibaba.com/schema/services/module-loader/adapters" xmlns:ml-factories="http://www.alibaba.com/schema/services/module-loader/factories" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.alibaba.com/schema/services http://localhost:8080/schema/services.xsd http://www.alibaba.com/schema/services/request-contexts http://localhost:8080/schema/services-request-contexts.xsd http://www.alibaba.com/schema/services/request-contexts/session/encoders http://localhost:8080/schema/services-request-contexts-session-encoders.xsd http://www.alibaba.com/schema/services/request-contexts/session/idgens http://localhost:8080/schema/services-request-contexts-session-idgens.xsd http://www.alibaba.com/schema/services/request-contexts/session/stores http://localhost:8080/schema/services-request-contexts-session-stores.xsd http://www.alibaba.com/schema/services/request-contexts/session/model-encoders http://localhost:8080/schema/services-request-contexts-session-model-encoders.xsd http://www.alibaba.com/schema/services/module-loader/adapters http://localhost:8080/schema/services-module-loader-adapters.xsd http://www.alibaba.com/schema/services/module-loader/factories http://localhost:8080/schema/services-module-loader-factories.xsd http://www.springframework.org/schema/beans http://localhost:8080/schema/www.springframework.org/schema/beans/spring-beans.xsd "> <!-- 支持${xxx}替换。 --> <services:property-placeholder> <services:property key="component">common</services:property> </services:property-placeholder> <!-- 共享配置。 --> <beans:import resource="common/webx-component-and-root.xml" /> <!-- 异常管道。 --> <beans:import resource="common/pipeline-exception.xml" /> <!-- 资源装载。 --> <beans:import resource="common/resources.xml" /> <!-- URI生成。 --> <beans:import resource="common/uris.xml" /> <!-- 综合设置。 --> <services:webx-configuration> <!-- 默认将productionMode设为true,建议在jetty插件中设置-DproductionMode=false。 --> <services:productionMode>${productionMode:true}</services:productionMode> <services:components defaultComponent="app1" /> </services:webx-configuration> <!-- 设置request/response/session。 --> <services:request-contexts xmlns="http://www.alibaba.com/schema/services/request-contexts"> <basic /> <buffered /> <lazy-commit /> <parser /> <set-locale defaultLocale="zh_CN" defaultCharset="UTF-8" /> <session> <id> <cookie path="/" maxAge="0" httpOnly="true" /> </id> <stores> <session-stores:cookie-store id="temporaryCookie"> <session-stores:cookie name="tmp" /> </session-stores:cookie-store> </stores> <store-mappings> <match name="*" store="temporaryCookie" /> </store-mappings> </session> </services:request-contexts> <!-- 支持上传文件。 --> <services:upload sizeMax="5M" /> <!-- 将beans暴露给模板。这里定义的tools可被所有components之间共享。 --> <services:pull xmlns="http://www.alibaba.com/schema/services/pull/factories"> <utils /> <page-tool /> <control-tool /> <uris-tool /> </services:pull> <!-- 装载模块。 --> <services:module-loader> <ml-factories:class-modules> <ml-factories:search-packages type="$1" packages="com.alibaba.webx.tutorial1.common.module.*" /> </ml-factories:class-modules> </services:module-loader> </beans:beans>
2、前端分析
所有和前台展示有关的文件,即模板,放在templates目录下,vm后缀的为Velocity的模板
对应的java代码
src/main/java/…/module。
Modules是基本编程模块:包括screen,control,action
Screen — 用来处理页面显示逻辑的module,主要功能就是显示一个页面
Control — 和screen类似,但可以被别的screen或layout引用,甚至可以跨越car应用
Action — 处理用户提交表单的module
Webx的页面布局以screen为主导,通过screen来查找其余的页面元素,然后通过一系列查找规则来查找页面元素Screen和control都可以有java类来驱动,但不是必须的,也就是说可以先写模板,后写类 ,也可以只写模板,不用构造对应类。
页面布局如下:
• Screen,代表页面的主体。
• Layout,代表页面的布局。
• Control,代表嵌在screen和layout中的页面片段。
3、Webx执行的流程
可参考:http://qa.taobao.com/?p=7830,http://qa.taobao.com/?p=7604
1)petstore称为Context Path。服务器把这个请求交给petstore应用来接管。
2) login.htm称为Servlet Path。在web.xml中把*.htm映射到Webx Controller Servlet,所以Webx Controller Servlet就接管了这个请求。
3) Webx Controller Servlet激活pipeline,继而调用AnalyzeURLValve来分析/ login.htm是什么意思。根据webx默认的映射规则,/ login.htm被转换成/ login.vm。
4、配置文件分析
参考:http://qa.taobao.com/?p=12800
(1)Webx2 PoolToll
在velocity模板中经常使用到pulltool,这是一些工具类,方便我们进行页面输出内容的控制,组织页面的展示,或者是直接取得web层相关的 一些对象,直接在vm中调用。pull在概念上可以形象的理解为"拉动",是由页面拉动业务逻辑,获取并控制需要展示的内容,而非应用程序推动 (push),这非常符合webx的页面驱动的模式。在页面进行渲染时,pulltool对象已被预先创建好,并被放入TemplateContext 中,在渲染页面时被调用并输出所需要的内容。 pulltool是由PullService管理的,PullService将pulltool纳入了Service框架的范畴进行管理,理论上我们可以 将任意组件封装为一个pulltool,或者将任意代码逻辑封装在一个pulltool中,只要实现PullTool接口,这个类便可以被 PullService管理起来进而可以在vm模板中直接使用,或者说,pulltool就是一些被PullService管理的组件,这些组件帮助我们控制页面上的内容。pulltool一般都会继承一个抽象类PullToolSupport,这个类方便对PullTool进行配置与调用,它包含了一些 与PullTool的配置与初始化有关的逻辑,它的子类只需要专注于自己需要对外提供的方法即可。而PullService提供了一个自动组装 TemplateContext的机制,通过这个机制,PullTool被put进TemplateContext,可以在模板中被直接使用。 PullTool 有四种不同的作用范围,
<service name="PullService" class="com.alibaba.service.pull.DefaultPullService"> <property name="tool.global"> <property name="util" value="com.alibaba.service.pull.LangToolSet"/> <property name="viewTool" value="com.alibaba.intl.web.webx.pull.IntlViewPullTool"/> <property name="constantTool" value="com.alibaba.turbine.util.template.ConstantTool"/> </property> <property name="tool.request"> <property name="rundata" value="com.alibaba.turbine.util.template.RunDataTool"/> <property name="page" value="com.alibaba.turbine.util.template.HtmlPageAttributeTool"/> <property name="control" value="com.alibaba.turbine.util.template.ControlTool"/> <property name="uri" value="com.alibaba.service.uribroker.URIBrokerTool"/> <property name="form" value="com.alibaba.service.form.FormTool"/> <property name="webuser" value="com.alibaba.intl.web.webx.pull.WebUserPullTool"/> </property> </service>
(2)Webx3 pooltool
pullTool的配置
Webx3 PullTool的配置形式上发生了改变、采用的是Spring Xml Schema的配置方式、例子如下:
<services:pull xmlns="http://www.alibaba.com/schema/services/pull/factories">
<!- Webx3 tools。 ->
<utils />
<rundata-tool />
<csrfToken />
<form-tool />
<control-tool />
<uris-tool />
<!- Petstore tools。 ->
<webx2-tool id="bundle"
class="com.alibaba.sample.petstore.web.common.util.ResourceBundleTool" scope="global" />
<webx2-tool id="petstoreUser"
class="com.alibaba.sample.petstore.web.common.util.PetstoreUserTool" scope="request" />
</services:pull>
Webx3对PullTool的配置进行了简化和封装、但是如果缺少文档的话、上面的有些配置可能就不那么容易理解
比如: <utils /> 这个标签其实表示的是开发者可以直接在Vm中使用com.alibaba.common.lang包下的一些工具类:
如ArrayUtil、StringUtil、SystemUtil等
其他的几个标签相对容易理解、如:rundata-tool代表$rundata、csrfToken代表$csrfToken、uris-tool表示的是UriBrokerTool、
可以在Vm使用Uribroker、另外webx2-tool标签表示的是使用Web3的兼容模式集成Web2下自定义的PullTool,scope属性表示的是
PullTool的作用级别
Webx3下自定义或扩展一个PullTool要比Webx2容易且有多种方法:
1、实现ToolFactory、或者ToolSetFactory接口、实现了后者可以创建一组pullTool
代码示例:
接下来只要将该类配置一下即可使用
<factory id="sampleTool" class="com.alibaba.citrus.service.pull.tool.SampleTool" />
2、采用Webx3提供的BeanTool
BeanTool是可以用于创建一个简单bean的tool factory
你可以将一个工具类或者简单的Spring容器的Bean只需通过简单的配置就可以成为一个PullTool,
BeanTool内部使用AutowireCapableBeanFactory的initializeBean方法将指定的Class动态初始化一个
Bean并注入到Spring容器中、同时该Bean可以作为一个PullTool使用:
配置如下:
<bean-tool id="sampleTool"
class="com.alibaba.citrus.service.pull.tool.SampleTool"
scope="global" />
这种方式的好处:
1你可以方便的将已有的一个工具类配置一下就可以变成PullTool而不需要专门实现任何接口、去除了对原有类的不必要侵入,
2可以将Spring容器的一个Bean作为PullTool使用
(3)webx3中webx.xml中request context配置
<services:request-contexts xmlns="http://www.alibaba.com/schema/services/request-contexts"> <basic /> <buffered /> <lazy-commit /> <parser /> <set-locale defaultLocale="zh_CN" defaultCharset="UTF-8" /> <session> <id> <cookie path="/" maxAge="0" httpOnly="true" /> </id> <stores> <session-stores:cookie-store id="temporaryCookie"> <session-stores:cookie name="tmp" /> </session-stores:cookie-store> </stores> <store-mappings> <match name="*" store="temporaryCookie" /> </store-mappings> </session> </services:request-contexts>