• 1. Webx简介第一课
  • 2. WebX框架基础WebX Packaging
  • 3. Webx应用的打包方法传统方式Webx方式War —— 是Web Application Archive的缩写 Car —— 是Component Archive的缩写 多个car可以组装成一个war
  • 4. Car在开发中的应用Car的目录结构和War基本相同,除了 不需要文件:WEB-INF/web.xml 不需要目录:WEB-INF/lib 开发时,可以把car当作war来开发、调试 部署时,可以把多个car组合成一个war WebX框架保证,无论下面哪种情况,对程序代码而言都是透明的: 将car以war的形式单独运行 或将多个car组合成一个war运行
  • 5. Petstore.war的组成home.car ├─css ├─images ├─templates │ ├─control │ ├─layout │ └─screen └─WEB-INF │ webx.xml │ └─classesuser.car ├─css ├─images ├─templates │ ├─control │ ├─layout │ └─screen │ └─WEB-INF │ webx.xml │ └─classesPetstore.war ├─home │ ├─css │ ├─images │ └─templates │ ├─control │ ├─layout │ └─screen ├─user │ ├─css │ ├─images │ └─templates │ ├─control │ ├─layout │ └─screen ├─store ├─admin │ └─WEB-INF ├─home │ webx.xml ├─user │ webx.xml ├─store ├─admin │ ├─lib └─classes
  • 6. WebX框架基础URL的解析与生成
  • 7. 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分析的规则是完全可以被改变的。
  • 8. URL的生成和解析URL相反,我们还需要在页面上生成指向其它页面的URL。 URL是由URIBrokerService来动态生成的。 使用URIBrokerService有什么好处呢? 集中管理 —— 全网站的URL均可在同一个配置文件中管理 可靠 —— 动态生成,不容易出错 规范 —— 例如在生成query string时,会自动URL encoding 透明 —— 应用程序、模板不需要知道最终生成的URL的样子,修改URL就变得很简单
  • 9. URL配置文件举例 http://toolkit.alibaba-inc.com/ /user login.vm
  • 10. 在模板中使用URIBroker的方法$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
  • 11. 在程序中使用URIBroker的方法 取得URIBrokerService: URIBrokerService uriBrokerService = (URIBrokerService) getWebxComponent() .getService(URIBrokerService.SERVICE_NAME); 取得指定名称的URIBroker: URIBroker uriBroker = uriBrokerService.getURIBroker( "petstoreLoginLink", rundata); 渲染URL: String url = uriBroker.render();
  • 12. WebX框架基础RunData
  • 13. RunData的功能封装了Request和Response对象 保存request scope的状态 透明地处理常规表单和multipart/form-data格式的表单数据 简化cookie的存取 提供透明的buffering支持
  • 14. RunData常用方法取得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)
  • 15. WebX框架基础页面布局
  • 16. Turbine风格的页面布局LayoutControlControlControlScreenPetstore SampleCopyright NoticeNavigation MenuMain Content
  • 17. Turbine风格的目录结构模板目录结构 src/webroot └─templates ├─control │ bottom.vm │ tabs.vm │ top.vm │ topNoLogo.vm │ ├─layout │ default.vm │ └─screen homepage.vmJava模块package结构 src/java └─com └─alibaba └─sample └─petstore └─web └─home └─module ├─screen │ Homepage.java ├─control └─action 开发turbine应用程序的基本单元是Module 实际应用中,大部分的module都是TemplateModule。TemplateModule由两部分构成:模板和Java模块:
  • 18. 实际例子:Petstore登录页面这个页面是怎么显示出来的呢?
  • 19. 实际例子:Petstore登录页面(过程)用户输入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
  • 20. 访问无模板的screen假设有下面的URL(注意后缀): http://localhost:7001/petstore/user/login.do 那么WebX将不会查找login.vm这个模板,而是直接执行screen: com.alibaba.sample.petstore.web.user.module.screen.Login 什么时候要使用这种URL呢? 不使用模板的情形 —— 模板只是一种文本生成技术,除此之外,还有其它技术。在某些情形下,使用模板不一定是最好的方法。 不需要返回可见的页面的情形 —— 例如一个被机器回调的URL。 重定向到另一个页面的情形 —— 有时一个页面自身不显示内容,而是重定向(内部/外部)到另一个页面。例如:支付宝的商家工具。
  • 21. WebX框架基础页面驱动
  • 22. 页面驱动什么是页面驱动? 以页面(view)为主导 先写页面,再写和页面配套的程序模块 通过规则,查找页面所对应的程序模块 页面驱动的好处? 符合WEB项目开发的流程: 在产品设计阶段就可以做出页面 在开发阶段对页面进行细化。 页面驱动的动力 —— Pull Tools
  • 23. Pull Tools看看petstore中的一个页面模板: 想想看:以上这些“红色”的变量是哪来的?
    #set ($group = $form.login.defaultInstance) …… ……
  • 24. WebX框架基础Turbine Modules
  • 25. Turbine ModulesModules是基本编程模块: Screen —— 用来处理页面显示逻辑的module Control —— 和screen类似,但可以被别的screen或layout引用,甚至可以跨越car应用 Action —— 处理用户提交表单的module 所有module都实现Module接口: public interface Module { void execute(RunData rundata) throws WebxException; }
  • 26. Screen Module的写法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
  • 27. Control Module的写法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
  • 28. Action Module的写法Action是用来处理用户提交的表单的(以petstore用户登录为例)
    ……
    程序这样写: public class LoginAction extends TemplateAction { public void doLogin(RunData rundata, TemplateContext context) throws WebxException { …… } } 每个action可以处理多个事件,例如:doLogin、doAdd、doDelete…全凭用户按下哪个HTML按钮。如果一切都不匹配,则自动执行doPerform。
  • 29. WebX框架基础表单处理
  • 30. 表单验证通过FormService和FormTool集成到WebX中 详见Toolkit Demo中的form演示 最基本的表单(不需要写程序) 国际化的表单(不需要写程序) 在Java代码处理表单 创建额外的出错信息 创建新的validator