Webx Turbine
建立在Webx Framework
的基础上,实现了页面渲染、布局、数据验证、数据提交等一系列工作。
Webx Turbine所遵循下面的设计理念包括:
页面驱动
约定胜于配置
页面布局:
其中:
Screen
,代表页面的主体。Layout
,代表页面的布局。Control
,代表嵌在screen
和layout
中的页面片段
处理页面的基本流程:Webx Turbine
的处理流程被定义在pipeline
中。Webx Framework
没有规定Pipeline
的内容,但Webx Turbine
却定义了一系列valves
。下面是一个Webx Turbine
推荐的pipeline
配置:
当用户以:localhost:8080
来访问webx的时候,首先WebxFrameworkFilter
接收请求,并一路到达pipeline
– 分析URL
分析URL的目的是取得target
。由于用户访问的URL中并没有提供path信息,通常被理解为:用户想要访问“主页”。AnalyzeURL valve
提供了一个可选的参数homepage
,即是在这种情况下起作用 —— http://localhost:8081/
对应的target
为homepage
。
需要注意的是,
target
不代表模板名,也不代表类名。Target只是一个抽象的概念 —— 当前页面需要达成的目标。Target可能被后续的valves解释成模板名、类名或者其它东西。
进入 – 多重分支
很明显,“homepage”
满足了第一个
所附带的条件:
,意思是target的后缀不存在(null)或为“jsp”或为“vm”。
– 执行action
和其它框架中的action
概念不同,在Webx Turbine中,action是用来处理用户提交的表单的。
因为本次请求未提供action参数,所以跳过该步骤。
– 查找并执行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类,只需要有模板就可以了。
– 渲染模板
这里用到两个规则: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。
– 内部重定向
在screen和action中,可以进行“内部重定向”。内部重定向实质上就是由
实施的 —— 如果没有重定向标记,就退出;否则循环到 标签。
和外部重定向不同,外部重定向是向浏览器返回一个302或303 response, 其中包含Location header, 浏览器看到这样的response以后,就会发出第二个请求。而内部重定向发生在pipeline内部,浏览器并不了解内部重定向。
接下来我们看一下petstore项目的pipeline.xml
依赖注入:
通过@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;
...
}
参数注入