注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

和申的个人主页

专注于java开发,1985wanggang

 
 
 

日志

 
 

淘宝框架WEBX(1)相关  

2012-01-03 21:22:45|  分类: WebX |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

URL的解析与生成

WebX的URL是怎样的呢?以下面的URL为例:

http://localhost:7001/petstore/user/account/edit.htm
URL scheme(协议):http:
Server name:localhost
Server port:7001
Context path:/petstore
Component path:/user
Servlet path:/account/edit.htm
Target:/account/edit.vm
分析URL是由AnalyzeURLValve完成的(后面会讲到),因此以上URL分析的规则是完全可以被改变的。
和解析URL相反,我们还需要在页面上生成指向其它页面的URL。
URL是由URIBrokerService来动态生成的。
使用URIBrokerService有什么好处呢?
集中管理 —— 全网站的URL均可在同一个配置文件中管理
可靠 —— 动态生成,不容易出错
规范 —— 例如在生成query string时,会自动URL encoding
透明 —— 应用程序、模板不需要知道最终生成的URL的样子,修改URL就变得很简单
<uri-config>
    <!-- 外部链接 -->
    <uri name="toolkitSite" expose="true">
        <serverURI>http://toolkit.alibaba-inc.com/</serverURI>
    </uri>
    <!-- 根据当前URL自动取得server name、port、context path等信息 -->
    <uri name="petstoreServer"/>
    <!-- 指向user.car的URL -->
    <turbine-uri name="userModule" expose="true" extends="petstoreServer">
        <componentPath>/user</componentPath>
    </turbine-uri>
    <!-- 指向user.car中的图片、静态内容的URL -->
    <turbine-content-uri name="userContent" expose="true" extends="userModule"/>
    <!-- 指向user.car中的登录页面 -->
    <turbine-uri name="petstoreLoginLink" expose="true" extends="userModule">
        <target>login.vm</target>
    </turbine-uri>
</uri-config>
$toolkitSite
生成结果:http://toolkit.alibaba-inc.com/
$petstoreServer
由于expose=false,所以不能直接使用
$userModule.setTarget("account/edit.vm")
生成结果:http://localhost:7001/petstore/user/account/edit.htm
$userContent.setContentPath("images/my.gif")
生成结果:http://localhost:7001/petstore/user/images/my.gif
$petstoreLoginLink
生成结果:http://localhost:7001/petstore/user/login.htm
 取得URIBrokerService:
URIBrokerService uriBrokerService = (URIBrokerService)getWebxComponent().getService(URIBrokerService.SERVICE_NAME);
取得指定名称的URIBroker:
URIBroker uriBroker = uriBrokerService.getURIBroker("petstoreLoginLink",  rundata);
渲染URL:
String url = uriBroker.render();
WebX框架基础  RunData
封装了Request和Response对象
保存request scope的状态
透明地处理常规表单和multipart/form-data格式的表单数据
简化cookie的存取
提供透明的buffering支持
取得HTTP request、response和session
rundata.getRequest()
rundata.getResponse()
rundata.getSession()
取得输出流(自动buffering)
rundata.getResponse().getWriter()
rundata.getResponse().getOutputStream()
取得query参数(无论是一般form还是multipart form)
rundata.getParameters().getString("id")
rundata.getParameters().getInt("quantity")
内部重定向
rundata.setRedirectTarget("homepage.vm")
外部重定向
rundata.setRedirectLocation("http://www.alibaba.com/")
设置content type和character encoding
rundata.setContentType("text/html")
rundata.setCharacterEncoding("UTF-8")
存取request scope的参数
rundata.getAttribute(key)
rundata.setAttribute(key, object)

页面布局

淘宝框架WEBX(1)相关 - 和申 - 和申的个人主页

开发turbine应用程序的基本单元是Module

实际应用中,大部分的module都是TemplateModule。TemplateModule由两部分构成:模板和Java模块:

淘宝框架WEBX(1)相关 - 和申 - 和申的个人主页淘宝框架WEBX(1)相关 - 和申 - 和申的个人主页

用户输入URL: http://localhost:7001/petstore/user/login.htm

分析URL取得target: /login.vm
根据target查找screen模板: /screen/login.vm
根据target查找screen模块的类:
com.alibaba.sample.petstore.web.user.module.screen.Login(找不到该类)
com.alibaba.sample.petstore.web.user.module.screen.Default(找不到该类)
com.alibaba.turbine.module.screen.TemplateScreen(默认screen类)
执行screen类,并渲染screen模板
根据target查找layout模板: /layout/login.vm(找不到) /layout/default.vm(找到)
渲染layout模板

渲染在layout模板中引用的两个control: home:top.vm 

在home.car中查找/control/top.vm home:bottom.vm

在home.car中查找/control/bottom.vm

假设有下面的URL(注意后缀):
http://localhost:7001/petstore/user/login.do
那么WebX将不会查找login.vm这个模板,而是直接执行screen:
com.alibaba.sample.petstore.web.user.module.screen.Login
什么时候要使用这种URL呢?
不使用模板的情形 —— 模板只是一种文本生成技术,除此之外,还有其它技术。在某些情形下,使用模板不一定是最好的方法。
不需要返回可见的页面的情形 —— 例如一个被机器回调的URL。
重定向到另一个页面的情形 —— 有时一个页面自身不显示内容,而是重定向(内部/外部)到另一个页面。例如:支付宝的商家工具。
页面驱动
什么是页面驱动?
以页面(view)为主导
先写页面,再写和页面配套的程序模块
通过规则,查找页面所对应的程序模块
页面驱动的好处?
符合WEB项目开发的流程:
在产品设计阶段就可以做出页面
在开发阶段对页面进行细化。
页面驱动的动力 —— Pull Tools
看看petstore中的一个页面模板:
<form action="$petstoreLoginLink" method="post">
  <input type="hidden" name="action" value="LoginAction"/>
  <input type="hidden" name="return" value="$!rundata.parameters.return"/>
  #set ($group = $form.login.defaultInstance)
  ……
  <input type="image" src="http://1985wanggang.blog.163.com/blog/$homeContent.getURI("images/btn_login.png")" name="event_submit_do_login" />
  ……
</form>
想想看:以上这些“红色”的变量是哪来的
<!-- 定义在webx.xml中 -->
<service name=“PullService” class=“com.alibaba.service.pull.DefaultPullService”>
    <!-- 全局pull tools -->
    <property name="tool.global">
        <property name="util" value="com.alibaba.service.pull.LangToolSet"/>
    </property>
    <!-- 局部pull tools -->
    <property name="tool.request">
        <property name="control" value="com.alibaba.turbine.util.template.ControlTool"/>
        <property name="control.sharing" value="false"/>
        <property name="form" value="com.alibaba.service.form.FormTool"/>
        <property name="form.sharing" value="false"/>
        <property name="page" value="com.alibaba.turbine.util.template.HtmlPageAttributeTool"/>
        <property name="page.sharing" value="true"/>
        <property name="rundata" value="com.alibaba.turbine.util.template.RunDataTool"/>
        <property name="rundata.sharing" value="true"/>
        <property name="uri" value="com.alibaba.service.uribroker.URIBrokerTool"/>
        <property name="uri.sharing" value="false"/>
    </property>
</service>
Turbine Modules
Modules是基本编程模块:
Screen —— 用来处理页面显示逻辑的module
Control —— 和screen类似,但可以被别的screen或layout引用,甚至可以跨越car应用
Action —— 处理用户提交表单的module
所有module都实现Module接口:
public interface Module {
    void execute(RunData rundata) throws WebxException;
}
Screen的功能就是显示一个页面,最简单的screen可以这样写:
public class SimpleScreen extends AbstractModule {
    public void execute(RunData rundata) throws WebxException {
        PrintWriter out = rundata.getResponse().getWriter();
        out.println("hello, world");
    }
}
但这种写法并不常用,99%的screen使用了模板技术:
public class MyTemplateScreen extends TemplateScreen {
    protected void execute(RunData rundata, TemplateContext context)
            throws WebxException {
        context.put("hello", "world");
    }
}
模板文件myTemplateScreen.vm可以这样写:

Hello, $hello   

显示结果:hello, world

Control和screen的写法完全类似:
public class SimpleControl extends AbstractModule {
    public void execute(RunData rundata) throws WebxException {
        PrintWriter out = rundata.getResponse().getWriter();
        out.println("hello, world");
    }
}
支持模板技术的control从TemplateControl类派生
public class MyTemplateControl extends TemplateControl {
    protected void execute(RunData rundata, TemplateContext context)
            throws WebxException {
        context.put("hello", "world");
    }
}
模板文件myTemplateControl.vm可以这样写:

Hello, $hello    

显示结果:hello, world

Action是用来处理用户提交的表单的(以petstore用户登录为例)
<form action="$petstoreLoginLink" method="post">
    <input type="hidden" name="action" value="LoginAction"/>
    ……
    <input type="image" src="http://1985wanggang.blog.163.com/blog/$homeContent.getURI("images/btn_login.png")“         name="event_submit_do_login" />
</form>
程序这样写:
public class LoginAction extends TemplateAction {
    public void doLogin(RunData rundata, TemplateContext context)
            throws WebxException {
        ……
    }
}
每个action可以处理多个事件,例如:doLogin、doAdd、doDelete…全凭用户按下哪个HTML按钮。如果一切都不匹配,则自动执行doPerform。
表单处理
通过FormService和FormTool集成到WebX中
详见Toolkit Demo中的form演示
最基本的表单(不需要写程序)
国际化的表单(不需要写程序)
在Java代码处理表单
创建额外的出错信息
创建新的validator
摘自:http://hi.baidu.com/274084093/blog/item/c4c252af481a8aeffbed508e.html
  评论这张
 
阅读(2352)| 评论(2)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016