事实是最近读《J2EE设计模式》讲述表达层模式的那几章,书中有一个前端控制器 command模式的workflow例子,就琢磨着可以很简单地扩展成一个MVC框架。 
						
							
6。前端控制器(FrontController),它的任务我们已经很清楚,初始化配置文件;存储所有action到ServletContext供整个框架使用;得到发起请求的path,提供给Dispachter查找相应的action;调用Dispatcher,执行getNextPage方法得到下一个页面的url并转发:
- 
 - public void init() throws ServletException { 
 - 
 -   //初始化配置文件 
 - 
 -   ServletContext context=getServletContext(); 
 -   String config_file =getServletConfig().getInitParameter("config"); 
 -   String dispatcher_name=getServletConfig().getInitParameter("dispatcher"); 
 -   if (config_file == null || config_file.equals("")) 
 -    config_file = "/WEB-INF/strutslet-config.xml"; //默认是/WEB-INF/下面的strutslet-config 
 -   if(dispatcher_name==null||dispatcher_name.equals("")) 
 -    dispatcher_name=Constant.DEFAULT_DISPATCHER; 
 -      
 -   try { 
 -    Map<String, ActionModel> resources = ConfigUtil.newInstance()  //工具类解析配置文件 
 -      .parse(config_file, context); 
 -    context.setAttribute(Constant.ACTIONS_ATTR, resources);  //存储在ServletContext中 
 -    log.info("初始化strutslet配置文件成功"); 
 -   } catch (Exception e) { 
 -    log.error("初始化strutslet配置文件失败"); 
 -    e.printStackTrace(); 
 -   } 
 - 
 -   //实例化Dispacher 
 - 
 -   try{ 
 -    Class c = Class.forName(dispatcher_name); 
 -       Dispatcher dispatcher = (Dispatcher) c.newInstance(); 
 -       context.setAttribute(Constant.DISPATCHER_ATTR, dispatcher); //放在ServletContext 
 -       log.info("初始化Dispatcher成功"); 
 -   }catch(Exception e) { 
 -     log.error("初始化Dispatcher失败"); 
 -       e.printStackTrace(); 
 -   } 
 - 
 -   ..... 
 
 doGet()和doPost方法我们都让它调用process方法:
- 
 - protected void process(HttpServletRequest request, 
 -    HttpServletResponse response) throws ServletException, IOException { 
 -   ServletContext context = getServletContext(); 
 - 
 -         //获取action的path  
 -   String reqURI = request.getRequestURI(); 
 -   int i=reqURI.lastIndexOf("."); 
 -   String contextPath=request.getContextPath(); 
 -   String path=reqURI.substring(contextPath.length(),i); 
 -    
 -   request.setAttribute(Constant.REQUEST_ATTR, path); 
 -   Dispatcher dispatcher = (Dispatcher) context.getAttribute(Constant.DISPATCHER_ATTR); 
 - 
 -   // make sure we don't cache dynamic data 
 -   response.setHeader("Cache-Control", "no-cache"); 
 -   response.setHeader("Pragma", "no-cache"); 
 - 
 -   // use the dispatcher to find the next page 
 -   String nextPage = dispatcher.getNextPage(request, context);//调用Dispatcher的getNextPage 
 - 
 -   // forward control to the view 
 -   RequestDispatcher forwarder = request.getRequestDispatcher("/" 
 -     + nextPage); 
 -   forwarder.forward(request, response);  //转发页面 
 -  } 
 
 7。最后,web.xml的配置就非常简单了,配置前端控制器,提供启动参数(配置文件所在位置,为空就查找/WEB-INF/下面的strutslet-config.xml文件),我们把所有以action结尾的请求都交给FrontController处理:
- 
 - <servlet> 
 -     <servlet-name>StrutsletController</servlet-name> 
 -     <servlet-class>com.strutslet.core.FrontController</servlet-class> 
 -     <!--   
 -     <init-param> 
 -          <param-name>config</param-name> 
 -          <param-value>/WEB-INFstrutslet-config.xml</param-value> 
 -     </init-param> 
 -     --> 
 -        <load-on-startup>0</load-on-startup> 
 -   </servlet> 
 -  <servlet-mapping> 
 -     <servlet-name>StrutsletController</servlet-name> 
 -     <url-pattern>*.action</url-pattern> 
 -  </servlet-mapping> 
 
 最后,让我们看看整个框架图: