webx学习(三)——Webx Turbine

Webx Turbine建立在Webx Framework的基础上,实现了页面渲染、布局、数据验证、数据提交等一系列工作。
Webx Turbine所遵循下面的设计理念包括:
页面驱动
约定胜于配置

页面布局:


其中:
Screen,代表页面的主体。
Layout,代表页面的布局。
Control,代表嵌在screen和layout中的页面片段

处理页面的基本流程:
Webx Turbine的处理流程被定义在pipeline中。Webx Framework没有规定Pipeline的内容,但Webx Turbine却定义了一系列valves。下面是一个Webx Turbine推荐的pipeline配置:

     <prepareForTurbine />
     <setLoggingContext />
     <analyzeURL homepage= "homepage" />
     <checkCsrfToken />
     <loop>
         <choose>
             <when>
                 <pl-conditions:target-extension-condition extension= "null, vm, jsp" />
                 <performAction />
                 <performTemplateScreen />
                 <renderTemplate />
             </when>
             <when>
                 <pl-conditions:target-extension-condition extension= "do" />
                 <performAction />
                 <performScreen />
             </when>
             <otherwise>
                 <exit />
             </otherwise>
         </choose>
         <breakUnlessTargetRedirected />
     </loop>
</services:pipeline>

当用户以:localhost:8080 来访问webx的时候,首先WebxFrameworkFilter接收请求,并一路到达pipeline

<analyzeURL> - 分析URL

分析URL的目的是取得target。由于用户访问的URL中并没有提供path信息,通常被理解为:用户想要访问“主页”。AnalyzeURL valve提供了一个可选的参数“homepage”,即是在这种情况下起作用 —— http://localhost:8081/对应的target为“homepage”。

需要注意的是,target不代表模板名,也不代表类名。Target只是一个抽象的概念 —— 当前页面需要达成的目标。Target可能被后续的valves解释成模板名、类名或者其它东西。

进入<choose> - 多重分支
很明显,“homepage”满足了第一个<when>所附带的条件:<target-extension-condition extension="null, vm, jsp">,意思是target的后缀不存在(null)或为“jsp”或为“vm”。
<performAction> - 执行action
和其它框架中的action概念不同,在Webx Turbine中,action是用来处理用户提交的表单的。
因为本次请求未提供action参数,所以跳过该步骤。
<performTemplateScreen> - 查找并执行screen。
这里要用到一个规则:target映射成screen module类名的规则。
假设target为xxx/yyy/zzz,那么Webx Turbine会依次查找下面的screen模块:

screen.xxx.yyy.Zzz,

screen.xxx.yyy.Default,

screen.xxx.Default,

screen.Default。

本次请求的target为homepage,因此它会尝试查找screen.Homepage和screen.Default这两个类。
如果找到screen类,Webx Turbine就会执行它。Screen类的功能,通常是读取数据库,然后把模板所需要的对象放到context中。
如果找不到,也没关系 —— 这就是“页面优先”:像homepage这样的主页,通常没有业务逻辑,因此不需要screen类,只需要有模板就可以了。

<renderTemplate> - 渲染模板
这里用到两个规则:target映射成screen template,以及target映射成layout template。
假设target为xxx/yyy/zzz,那么Webx Turbine会查找下面的screen模板:/templates/screen/xxx/yyy/zzz。Screen模板如果未找到,就会报404 Not Found错误。 找到screen模板以后,Webx Turbine还会试着查找下面的layout模板:

/templates/layout/xxx/yyy/zzz

/templates/layout/xxx/yyy/default

/templates/layout/xxx/default

/templates/layout/default

Layout模板如果找不到,就直接渲染screen模板;如果存在,则把渲染screen模板后的结果,嵌入到layout模板中。
Layout模板和screen模板中,都可以调用control。每个页面只有一个screen,却可以有任意多个controls。

<breakUnlessTargetRedirected> - 内部重定向
在screen和action中,可以进行“内部重定向”。内部重定向实质上就是由<breakUnlessTargetRedirected>实施的 —— 如果没有重定向标记,就退出;否则循环到<loop>标签。
和外部重定向不同,外部重定向是向浏览器返回一个302或303 response,其中包含Location header,浏览器看到这样的response以后,就会发出第二个请求。而内部重定向发生在pipeline内部,浏览器并不了解内部重定向。

接下来我们看一下petstore项目的pipeline.xml

<services:pipeline>
 
         <!-- 初始化turbine rundata,并在pipelineContext中设置可能会用到的对象(如rundata、utils),以便valve取得。 -->
         <pl-valves:prepareForTurbine />
 
         <!-- 设置日志系统的上下文,支持把当前请求的详情打印在日志中。 -->
         <pl-valves:setLoggingContext />
 
         <!-- 分析URL,取得target。 -->
         <pl-valves:analyzeURL homepage= "homepage" />
 
         <!-- 检查csrf token,防止csrf攻击和重复提交。假如request和session中的token不匹配,则出错,或显示expired页面。 -->
         <pl-valves:checkCsrfToken />
 
         <!-- 检查页面的授权,如果当前用户无权访问该页面,则跳转到petstoreLogin页面 -->
         <pl-valves:pageAuthorization callbackClass= "com.alibaba.sample.petstore.web.common.PetstoreUserAuth" />
 
         <pl-valves:loop>
             <pl-valves:choose>
                 <when>
                     <!-- 执行带模板的screen,默认有layout。 -->
                     <pl-conditions:target-extension-condition extension= "null" />
                     <pl-valves:performAction />
                     <pl-valves:performTemplateScreen />
                     <pl-valves:renderTemplate />
                 </when>
                 <when>
                     <!-- 执行不带模板的screen,无layout。 -->
                     <pl-conditions:target-extension-condition extension= "do" />
                     <pl-valves:performAction />
                     <pl-valves:performScreen />
                 </when>
                 <when>
                     <!-- 创建JSON,无模板,无layout。 -->
                     <pl-conditions:target-extension-condition extension= "json" />
                     <pl-valves:performScreen />
                     <pl-valves:renderResultAsJson />
                 </when>
                 <when>
                     <!-- 读取资源文件。 -->
                     <pl-conditions:path-condition name= "/petstore/images/(.+)" />
                     <pl-valves:getResource name= "/petstore/images/$1" />
                 </when>
                 <otherwise>
                     <!-- 将控制交还给servlet engine。 -->
                     <pl-valves:exit />
                 </otherwise>
             </pl-valves:choose>
 
             <!-- 假如rundata.setRedirectTarget()被设置,则循环,否则退出循环。 -->
             <pl-valves:breakUnlessTargetRedirected />
         </pl-valves:loop>
 
     </services:pipeline>

依赖注入:

通过@Autowired annotation注入

public class LoginAction {
     @Autowired
     private UserManager userManager;
     ...
}

注入request、response和session对象

public class LoginAction {
     @Autowired
     private HttpServletRequest request;
 
     @Autowired
     private HttpServletResponse response;
 
     @Autowired
     private HttpSession session;
     ...
}

参数注入


转自本人内网空间:@璞尧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值