Best way to dynamically load an action controller?
Say all requests go through a front controller. The front controller delegates that request to a particular action controller. The name of the controller, and the name of the action comes from the URL. What's the cleanest way to get an instance of the action controller based on its name, then run a method in it, alo based on its name. Example:
You've got action controllers for two different areas of your application, "forum" and "store". Each of these controllers will deal with different requests, but the front controller is the component which determines the class and the method to invoke.
The controllers have a basic skeleton layout like so:
org.yoursite.controller.actions.ForumActions;
publicclass ForumActionsextends ActionController{
publicvoid executeCreatePost(){
//deal with the "CreatePost" action
}
publicvoid executeDeleteThread(){
//you get the idea
}
}
org.yoursite.controller.actions.StoreActions;
publicclass StoreActionsextends ActionController{
publicvoid executeViewCart(){
//
}
publicvoid executeAddItem(){
//
}
}
You make a request to http://site.tld/servlet/FrontController?module=store&action=viewCart
The FrontController has enough information to know what you want to do:
StoreController ctl =new StoreController();
ctl.executeViewCart();
But what's the cleanest way to actually do that locating of the class, instantiating it and then running the correct method? Reflection? Can anyone give an example of how relfection can be used? I've got this but it seems to to sporadically throw "MethodInvokationException" errors if the servlet container has not been used for a while, then it starts working again after the first rquest has erred.
My code so far... not too happy with it:
/**
* Get an instance of the action controller for this request.
* @return ActionController
*/
public ActionController getActionController()throws ActionNotFoundException{
if (actionController ==null){
try{
Class actionClass = Class.forName("org.w3style.controllers.actions." + getModuleName() +"Actions");
actionController = (ActionController) actionClass.newInstance();
}catch (Exception e){
thrownew ActionNotFoundException("Action controller class for " + getModuleName() +" cannot be found." + e);
}
}
return actionController;
}
/**
* Run the requested action from the cotroller.
*/
protectedvoid doExecuteAction()throws ActionNotFoundException{
ActionController ac = getActionController();
try{
Class acClass = ac.getClass();
Class[] params ={};
Object[] args ={};
Method acMethod = acClass.getMethod("execute" + getActionName(), params);
acMethod.invoke(ac, args);
}catch (Exception e){
thrownew ActionNotFoundException("Action " + getActionName() +" cannot be found." + e);
}
}

