|
|
有两种分发器:叶分发器(LeafDispatcher)和分发器组(DispatcherGroup)。他们都是 org.velocityweb.dispatcher.Dispatcher 的子类。分发器组可以包含叶分发器。分发器组可以包含分发器组。叶分发器和分发器组之间的关系,就像文件和目录之间的关系。
每种分发器有一个 URL ID。本框架会使用这些 IDs 来生成 URL ID 树。当新的 URL 请求被控制器接收到,比如,
http://<somedomain>:<port>/<ControllerServletPath>?m1=cart&m2=add_item_to_cart&item_id=EST-11
控制器会在根控制器中查找 "cart" ,然后找到 CartDispatcherGroup。找到后,继续在 CartDispatcherGroup 中查找"add_item_to_cart",结果找到 AddItemToCartDispatcher。由于 AddItemToCartDispatcher 是一个叶分发器,AddItemToCartDispatcher 会从 request 中读取数据,调用后台的 service/DAO 函数,然后,往 WebAppContext 或者 session 中保存结果数据。VelocityWeb 会合并 WebAppContext 中的数据到用户指定的 HTML 模板中。然后用户就可以看到动态的 HTML 网页了。
网页布局可以定义在叶分发器和分发器组上。当分发器组有布局,所有这个组里面的东西,都会使用这个布局。比如,如果根分发器包含一个带有布局 l1 的分发器组 g1,g1 包含一个带有布局 l2 的分发器组 p2, p2 包含一个带有布局 l3 的叶分发器 d1。则 d1 的页面数据显示在 l3 里,外面是 l2,再外面是 l1。
在大多数 J2EE 项目中,布局会像示例程序 VPetstore 一样简单。那就是只有一层分发器组。可以直接在分发器组上定义布局。比如:
public class CartDispatcherGroup extends DispatcherGroup {
static {
DispatcherTreeManager.addParentChildrenRelationship(
CartDispatcherGroup.class, AddItemToCartDispatcher.class);
DispatcherTreeManager.addParentChildrenRelationship(
CartDispatcherGroup.class, ViewCartDispatcher.class);
DispatcherTreeManager.addParentChildrenRelationship(
CartDispatcherGroup.class, UpdateCartDispatcher.class);
DispatcherTreeManager.addParentChildrenRelationship(
CartDispatcherGroup.class, RemoveItemFromCartDispatcher.class);
}
public CartDispatcherGroup() {
this.setPageLayout(new VPetStorePageLayout());
}
public String getUrlId() {
return "cart";
}
}
public class AddItemToCartDispatcher extends QueryDispatcher {
public boolean process(HttpServletRequest request, WebAppContext webContext, Controller controller)
throws Exception {
...
return forward(ViewCartDispatcher.class, request, webContext, controller);
}
public String getUrlId() {
return "add_item_to_cart";
}
}
在 VelocityWeb 框架里,叶分发器用来读取请求的数据,调用 service/DAO,然后将数据放入 WebContext 对象中。如果没有错误,没有异常,则在 process() 里返回 true。
public class UpdateUserInfoDispatcher extends QueryDispatcher {
public boolean process(HttpServletRequest request, WebAppContext context, Controller controller)
throws Exception{
this.setHtmlTemplateFileName("user/update_user_info.htm");
this.setPageTitle("Update user info");
context.put("result_win_url",
DispatcherTreeManager.getUrl(ShowProcessResultDispatcher.class));
context.put("target_process_url",
DispatcherTreeManager.getUrl(UpdateUserInfoProcessDispatcher.class));
// get user from session
Account user = (Account) controller.getSessionUser(request);
//reload user data, some others may change it
UserService srv = new UserService(context);
user = srv.getUserById(user.getUserid());
context.put("user_id", user.getUserid());
//show account information
context.put("first_name", user.getFirstname());
context.put("last_name", user.getLastname());
context.put("email", user.getEmail());
context.put("phone", user.getPhone());
context.put("address1", user.getAddr1());
context.put("address2", user.getAddr2());
context.put("city", user.getCity());
context.put("state", user.getState());
context.put("zip", user.getZip());
context.put("country", user.getCountry());
//show user profile
Profile profile = srv.getProfileById(user.getUserid());
context.put("langpref", profile.getLangpref());
context.put("favcategory", profile.getFavcategory());
context.put("mylistopt", profile.getMylistopt());
context.put("banneropt", profile.getBanneropt());
return true;
}
public String getUrlId() {
return "update_user";
}
}
每个叶分发器有自己的事务级别、HTML 模板文件名,文件编码,页面标题,布局。如果叶分发器属于某个分发器组,则也会使用分发器组的布局。页面标题标签通常定义在布局文件中。
|
|