1.0          Other languages
 
 

3.3 Dispatcher

 
 

There are two kinds of dispatchers: LeafDispatcher and DispatcherGroup. They are both sub-classes of org.velocityweb.dispatcher.Dispatcher. DispatcherGroup can contain LeafDispatcher. DispatcherGroup can contain DispatcherGroup. The relationship between LeafDispatcher and DispatcherGroup is something like file and file folder.

Each dispatcher has one URL ID. The framework will use these IDs to generate a URL ID tree. When a new URL request is received by controller, for example,

http://<somedomain>:<port>/<ControllerServletPath>?m1=cart&m2=add_item_to_cart&item_id=EST-11

Controller will try to find "cart" in root dispatchers. And it find CartDispatcherGroup. After found, it continue finding "add_item_to_cart" in CartDispatcherGroup, and it find AddItemToCartDispatcher. As AddItemToCartDispatcher is a LeafDispatcher, AddItemToCartDispatcher will read data from request, and call background service/DAO functions, and then, save result data in WebAppContext or session. VelocityWeb will merge data in WebAppContext into user defined HTML template. And user will see the dynamic HTML pages.

Layout can be defined at both DispatcherGroup and LeafDispatcher. When a DispatcherGroup has layout, all items in this group will use it. For example, if root dispatcher contains dispatch group g1 with layout l1, g1 contains dispatch group p2 with layout l2, and p2 contains leaf dispatcher d1 with layout l3. Then the result page content of d1 will show in l3, surrounded with l2, and then surrounded by l1.

In most J2EE project, the things will be simple as VPetstore sample project. That is only one level of dispatch group. you just need to define layout at dispatch group. for example:

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";
        }
}

In VelocityWeb, leaf dispatcher is used to get request data, and call service/DAO, and put data into WebContext object. If no error, no exception, then return true in process().

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";
        }
}

Each leaf dispatcher has it's own transaction level, HTML template file name, file charset name, page title, layout. If leaf dispatcher belongs to some dispatcher group, it will use the layout for dispatcher group. Page title tag is normally defined in layout page.