Webx3学习笔记(2)——基本流程

Webx3项目是运行在jetty/tomcat这种Web应用容器中的,Web应用的模式都是请求-响应的。一个请求通过浏览器发出,封装为HTTP报文到达服务端,被容器接受到,封装为HttpRequest和HttpResponse等,然后进入Webx3的领域,通过Webx3的一套Pipeline机制到达指定的后台,调用Java类获取数据或处理,渲染Velocity模板并返回到客户端进行显示。简单示意图如下:

未命名图片

pipeline:

未命名图片

下面通过分析 Webx3学习笔记(1)——Hello, World!中生成的源码来理解Webx3的基本流程:

以http://localhost:8081/?home 这个页面作为起点吧,通过观察源码可知这个页面是结合了app1/templates/layout/default.vm和app1/templates/screen/index.vm两个模板进行渲染出来的(怎么找到这两个页面的我暂时也不清楚)。这个页面就是一系列简单demo的集合,下面挑有代表性的几个进行分析:

无模板Screen

url: http://localhost:8081/simple/say_hi.do

先看一下pipeline.xml中比较重要的loop部分,除了作者本身的注释,也加上了我自己的理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
< pl-valves:loop >
< pl-valves:choose >
< when >
<!-- 执行带模板的screen,默认有layout。 -->
< pl-conditions:target-extension-condition extension = "null" />
 
   <!-- <strong>会去查找action包下面指定类的指定方法</strong> -->
   < pl-valves:performAction />
   <!-- <strong>会去模块的screen包下面寻找同名的Screen类</strong>-->
   < pl-valves:performTemplateScreen />
   <!-- <strong>会去app1/templates/screen下寻找同名的vm模板,然后再找app1/templates/layout下同名的layout模板,最后把layout和screen模板拼起来进行渲染并返回,要是实在找不到layout,就只渲染screen。</strong>
-->
   < pl-valves:renderTemplate />
</ when >
< when >
<!-- 执行不带模板的screen,无layout。 -->
< pl-conditions:target-extension-condition extension = "do" />
   <!-- 同上 -->
   < pl-valves:performAction />
   <!-- <strong>基本同上,不过这个步骤是必须的,无法跳过。而且这种Screen类是有输出的,类似Servlet</strong> -->
   < pl-valves:performScreen />
</ when >
< when >
<!-- 创建JSON,无模板,无layout。 -->
   < pl-conditions:target-extension-condition extension = "json" />
   < pl-valves:performScreen />
   < pl-valves:renderResultAsJson />
</ when >
< otherwise >
<!-- 将控制交还给servlet engine。 -->
< pl-valves:exit />
</ otherwise >
</ pl-valves:choose >
<!-- 假如rundata.setRedirectTarget()被设置,则循环,否则退出循环。 -->
< pl-valves:breakUnlessTargetRedirected />
</ pl-valves:loop >

本例中请求的后缀是.do,所以会执行:

1
2
3
4
5
< when >
< pl-conditions:target-extension-condition extension = "do" />
< pl-valves:performAction />
< pl-valves:performScreen />
</ when >

performAction是表单提交才会执行的流程,所以这里直接略过,执行到了performScreen,因为target为simple/say_hi.do,所以该方法去寻找app1.module.screen.simple下寻找同名Java类,而且有一个命名转换规则:say_hi->SayHi。于是我们就找到了SayHi.java,并调用其execute()方法。

1
2
3
4
5
6
7
8
9
10
11
public class SayHi {
@Autowired
private HttpServletResponse response;
public void execute() throws Exception {
// 设置content type,但不需要设置charset。框架会设置正确的charset。
response.setContentType( "text/plain" );
// 如同servlet一样:取得输出流。
PrintWriter out = response.getWriter();
out.println( "Hi there, how are you doing today?" );
}
}

【注意对于第7个例子,say_hello_1.do中没有找到execute()方法,就默认去找了doPerform(),say_hello_1/chinese.do,则会去调用其doChinese()方法。这是种不太常用的方式。】

有模板Screen+表单处理

url:http://localhost:8081/form/register.htm

url后缀名为.htm,会被转换为无后缀的形式,进行如下处理流程:

1
2
3
< pl-valves:performAction />
< pl-valves:performTemplateScreen />
< pl-valves:renderTemplate />

这也不是一个表单请求,所以略过performAction,执行performTemplateScreen ,去app1.module.screen.form包下寻找Register.Java,并没有找到,但是也没关系【performTemplateScreen 情况下,Screen的Java类并不是必须的】,继续执行renderTemplate,去app1/templates/screen/form/下寻找register.vm,这次找到了,再结合app1/templates/layout/default.vm进行渲染,default.vm就是一个html骨架,主要使用register.vm进行填充。

register.vm:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$page .setTitle( "Register" )
<form action= "$app1Link.setTarget(" form/register ")" method= "post" >
  $csrfToken .hiddenField
  <input type= "hidden" name= "action" value= "register_action" />
  #set ( $group = $form .register.defaultInstance)
  <p>Hello, what's your name?</p>
  # if (! $group .name.valid)
    <p> $group .name.message</p>
  # end
  <p>
    <input type= "text" name= "$group.name.key" value= "$!group.name.value" />
    <input type= "submit" name= "event_submit_do_register" />
  </p>
</form>

这样就在前端看到了这样的界面:
未命名图片

其中有很多细节值得注意,让我们来关注一下register.vm:

表单的主体部分:

1
2
3
4
5
6
7
8
</pre>
<pre>#set ( $group = $form .register.defaultInstance)</pre>
<pre><p>Hello, what's your name?</p></pre>
<pre># if (! $group .name.valid)
  <p> $group .name.message</p>
  # end
  <input type= "text" name= "$group.name.key" value= "$!group.name.value" /></pre>
<pre>

$form.register是在WEB-INF/app1/form.xml里定义的:

1
2
3
4
5
6
7
8
9
</pre>
<pre><group name= "register" extends = "csrfCheck" >
  <field name= "name" displayName= "你的名字" >
  <fm-validators:required-validator>
  <message>必须填写 ${displayName}</message>
  </fm-validators:required-validator>
  </field>
  </group></pre>
<pre>

这个名为register的FormGroup有一个属性名为name,该属性还有一个erquired-validator,意思就是必填项。所以在表单内容填写完毕后就会把值付给register的对应属性传到action那里进行处理。

然后看action部分,如果我们把<from action=”…”>中的action属性给删除掉,按理说提交表单时就会报错,可是并没有发生这样的情况,原来Webx3中的表单action是在这里进行配置的:

1
2
3
4
5
6
</ pre >
< pre >$csrfToken.hiddenField
  < input type = "hidden" name = "action" value="<strong>register_action</ strong >"/>
  ……
  < input type = "submit" name="event_submit_<strong>do_register</ strong >"/></ pre >
< pre >

加粗部分共同决定了这个表单提交时会去找app1.module.action包下面的RegisterAction.doregister()方法。让我们去看看这个方法:

1
2
3
4
5
6
</pre>
<pre> public void doRegister( @FormGroup ( "register" ) Visitor visitor, Navigator nav) {
  String name = visitor.getName();</pre>
<pre>nav.redirectTo( "app1Link" ).withTarget( "form/welcome" ).withParameter( "name" , name);</pre>
<pre>}</pre>
<pre>

@FormGroup就是刚刚说过的,这里会读取其属性并注入到Visitor中。Navigator是个内置的类,直接用就行了。
这里在接收到表单请求后会把应用重定向到form/welcome去,同时带一个参数name,就是刚刚表单中读取的值。

然后form/welcome会走同样的流程:

1
2
3
4
< pl-valves:performAction />
  < pl-valves:performTemplateScreen />
  < pl-valves:renderTemplate /></ pre >
< pre >
action略过,performTemplateScreen会找到app1.module.screen.form.Welcome.java:
1
2
3
4
5
</pre>
<pre>public void execute(@Param("name") String name, Context context) {
  context.put("name", name);
  }</pre>
<pre>

@Param(“name”) String name 等价于String name = HttpRequest.getParameter(“name”); 这样写能省几行代码。
这个类的作用仅仅是把request里的name参数写进Velocity的context里面。

然后renderTemplate会找到app1/template/screen/form/welcome.vm:

1
2
3
4
</pre>
<pre> $page .setTitle( "Welcome, $name" )
  <p>Welcome, $name !</p></pre>
<pre>

同样是结合layout渲染输出。

最终展示的界面为:

未命名图片

至此一个表单的历程已经全部走完。

转载于:https://www.cnblogs.com/Vae1990Silence/p/4618660.html

该文档为官方webx框架文档,对webx进行了全面的讲解,非常实用,并附学习的Demo 为什么要用Webx而不是其它的开源框架? 现在有很多Java的Web框架可供选择,并且它们也都是免费的。例如: • Struts • Webwork • Tapestry • Spring MVC 以上框架都是非常优秀的。说实话,如果阿里巴巴网站在2001年开始,就有这么多可选择的话,无论选择哪一个都不会有问题。因为这些年来,所有的开源Web框架都在互相学习、并趋于相似。Webx也不例外,它吸收了其它框架的很多想法。因此,当你使用Webx的时候,你会觉得在很多方面,它和其它开源的框架非常类似。我并不是说所有的框架都一样好,而是说只要假以时日,所有的框架在发展过程中,必然会积聚好的方面,淘汰坏的方面,从而变得足够好。从这个角度看,的确没有特别明显的理由来选择Webx,但也没有明显的理由不选择Webx。 另一方面,由于每一种框架采用不同的设计,必然会有各自的优势。Webx也是如此 —— 它在某些方面有一些独到的设计,超越了同类框架。Webx有哪些优势呢? Webx的优势 成熟可靠性 这个优势主要是针对阿里巴巴及属下网站而言。因为Webx在阿里巴巴和淘宝用了很多年。对于这种超大访问量的电子商务网站,Webx经受了考验,被证明是成熟可靠的。 开放和扩展性 • 对Spring的直接支持 —— Spring是当今主流的轻量级框架。Webx 3.0和Spring MVC一样, 完全建立在Spring框架之上,故可运用Spring的所有特性。 • 扩展性 —— Webx 3.0对Spring做了扩展,使Spring Bean不再是“bean”,而是升级成“组件”。一个组件可以扩展另一个组件,也可以被其它组件扩展。这种机制造就了Webx的非常好的扩展性,且比未经扩展的Spring更易使用。 • 开放性 —— Webx被设计成多个层次,层次间的分界线很清晰。每个层次都足够开放和易于扩展。你可以使用全部的Webx,也可以仅仅使用到Webx的任何一个层次。 引言 ............................................................................................................................... ix 1. 阅读向导 ............................................................................................................. ix 2Webx是什么? .................................................................................................... ix 3Webx的历史 ....................................................................................................... ix 4. 为什么要用Webx而不是其它的开源框架? ............................................................. x 5. Webx的优势 ........................................................................................................ x 5.1. 成熟可靠性 ................................................................................................ x 5.2. 开放和扩展性 ............................................................................................. x 6. Webx还缺少什么? .............................................................................................. x 部分 I. Webx框架概览 ......................................................................
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值