一、 实现自定义MVC的体系结构图

  1、ModelI模式开发Web应用时,分两种情况:

  纯JSP技术方式开发

  JSP+JavaBean方式开发

  2、ModelI模式开发的不足:

  JSP页面中嵌入大量的Java代码,可读性差。

  大量代码在JSP中难以复用。

  后期维护及扩展的难度大。

  3、为了克服ModelI模式的缺陷,引入了ModelII的模式开发

  ModelII模式体现了基于MVC(Model-View-Controller,模型-视图-控制器)的设计模式,简单的说,ModelII模式就是将数据显示、流程控制和业务逻辑处理分离,使之相互独立。

  4、MVC设计模式由3个部分组成各部分的作用。

  Model:模型,主要用于数据和业务的处理。

  View:视图,用于数据显示。

  Controller:控制器,用于流程控制。

  5、MVC设计模式的特点

  一个模型可以对应多个视图。

  显示与逻辑控制分离。

  分层控制,减低了代码间的耦合。

  二、 我们如何创建一个自己的MVC框架??

  (一)我们要在lib里面准备一个夹包

  dom4j-1.6.1.jar主要作用:解析xml文件

  (二)准备配置文档(在src下)

  <!DOCTYPEmyframework[

  <!ELEMENTmyframework(actions)>

  <!ELEMENTactions(action*)>

  <!ELEMENTaction(result*)>

  <!ATTLISTactionnameCDATA#REQUIRED

  classCDATA#REQUIRED

  >

  <!ATTLISTresultnameCDATA#IMPLIED

  redirect(true|false)"false"

  >

  ]>

  解释:

  解释:根据上述约束完成的“*”代表该节点可以出现多次

  <myframework>

  <actions>

  <actionname="LoginAction"class="cn.action.LoginAction">

  <resultname="success">success.jsp</result>

  <resultname="login">login.jsp</result>

  </action>

  </actions>

  </myframework>

  (三)自己准备一个Action接口,用于放入结果集和执行方法

  packagecn.framework;

  importjavax.servlet.http.HttpServletRequest;

  importjavax.servlet.http.HttpServletResponse;

  publicinterfaceAction{

   publicfinalStringSUCCESS="success";

   publicfinalStringERROR="error";

   publicfinalStringLOGIN="login";

   publicfinalStringINPUT="input";

   publicStringexecute(HttpServletRequestrequest,

   HttpServletResponseresponse);

  }

  (四)定义一个ResultMapping用来存放result节点

  packagecn.framework;

  publicclassResultMapping{

   //result节点名字

   privateStringname;

   //是否重定向

   privatebooleanredirect;

   //跳转的页面

   privateStringurl;

   publicResultMapping(){

   }

   publicResultMapping(Stringname,booleanredirect,Stringurl){

   this.name=name;

   this.redirect=redirect;

   this.url=url;

   }

   publicStringgetName(){

   returnname;

   }

   publicvoidsetName(Stringname){

   this.name=name;

   }

   publicbooleanisRedirect(){

   returnredirect;

   }

   publicvoidsetRedirect(booleanredirect){

   this.redirect=redirect;

   }

   publicStringgetUrl(){

   returnurl;

   }

   publicvoidsetUrl(Stringurl){

   this.url=url;

   }

  }

  (五)定义一个ActionMapping用来存放Action节点

  packagecn.framework;

  importjava.util.HashMap;

  importjava.util.Map;

  publicclassActionMapping{

   //Action名称

   privateStringname;

   //Action名称对应的Action的类的全称

   privateStringclassName;

   //result集合

   privateMap<String,ResultMapping>results=newHashMap<String,ResultMapping>();

   publicActionMapping(){

   }

   publicActionMapping(Stringname,StringclassName,Map<String,ResultMapping>results){

   super();

   this.name=name;

   this.className=className;

   this.results=results;

   }

   publicStringgetName(){

   returnname;

   }

   publicvoidsetName(Stringname){

   this.name=name;

   }

   publicStringgetClassName(){

   returnclassName;

   }

   publicvoidsetClassName(StringclassName){

   this.className=className;

   }

   publicMap<String,ResultMapping>getResults(){

   returnresults;

   }

   publicvoidsetResults(Map<String,ResultMapping>results){

   this.results=results;

   }

  }

  (六)准备一个ActionMappingManager是用来管理ActionMapping的

  packagecn.framework;

  importjava.io.InputStream;

  importjava.util.HashMap;

  importjava.util.List;

  importjava.util.Map;

  importorg.dom4j.Attribute;

  importorg.dom4j.Document;

  importorg.dom4j.Element;

  importorg.dom4j.io.SAXReader;

  publicclassActionMappingManager{

   Map<String,ActionMapping>actionMapping=newHashMap<String,ActionMapping>();

   publicActionMappingManager(){

   init();

   }

   publicActionMappinggetActionMapping(StringactionName){

   returnactionMapping.get(actionName);

   }

   publicActionMappingManager(StringfileName){

   }

   publicMap<String,ActionMapping>getActionMapping(){

   returnactionMapping;

   }

   publicvoidsetActionMapping(Map<String,ActionMapping>actionMapping){

   this.actionMapping=actionMapping;

   }

   publicstaticvoidmain(String[]args){

   newActionMappingManager().init();

   }

   publicvoidinit(){

   InputStreamis=this.getClass().getResourceAsStream("/myframework.xml");

  

   SAXReadersr=newSAXReader();

   try{

   Documentdoc=sr.read(is);

   ElementelRoot=doc.getRootElement();

   List<Element>listActions=elRoot.elements();

   for(ElementelActions:listActions){

   List<Element>listAction=elActions.elements();

   for(ElementelAction:listAction){

   ActionMappingaMapping=newActionMapping();

   AttributeattName=elAction.attribute("name");

   AttributeattClass=elAction.attribute("class");

   aMapping.setName(attName.getValue());

   aMapping.setClassName(attClass.getValue());

   List<Element>listResult=elAction.elements();

   for(ElementelResult:listResult){

   ResultMappingrMapping=newResultMapping();

   AttributeattResultName=elResult.attribute("name");

   AttributeattResultRedirect=elResult.attribute("redirect");

   rMapping.setName(attResultName.getValue());

   rMapping.setRedirect(Boolean.parseBoolean(attResultRedirect.getValue()));

   rMapping.setUrl(elResult.getTextTrim());

   aMapping.getResults().put(rMapping.getName(),rMapping);

   }

   actionMapping.put(aMapping.getName(),aMapping);

   }

   }

   }catch(Exceptione){

   e.printStackTrace();

   }

   }

  }

  (七)利用反射机制找到自己的实列

  packagecn.framework;

  publicclassActionManager{

   publicstaticActioncreateAction(StringclassName){

   Class<?>clz=null;

   try{

   clz=Thread.currentThread().getContextClassLoader().loadClass(className);

   }catch(Exceptionex){

   ex.printStackTrace();

   }

   try{

   if(clz==null){

   clz=Class.forName(className);

   }

   }catch(Exceptionex){

   ex.printStackTrace();

   }

   Actionaction=null;

   try{

   action=(Action)clz.newInstance();

   }catch(Exceptionex){

   ex.printStackTrace();

   }

   returnaction;

   }

  }

  (八)写一个业务逻辑

  packagecn.action;

  importjavax.servlet.http.HttpServletRequest;

  importjavax.servlet.http.HttpServletResponse;

  importcn.framework.Action;

  publicclassLoginActionimplementsAction{

   @Override

   publicStringexecute(HttpServletRequestrequest,HttpServletResponseresponse){

   return"success";

   }

  }

  (九)核心控制器Servlet

  packagecn.framework;

  importjava.io.IOException;

  importjavax.servlet.ServletConfig;

  importjavax.servlet.ServletException;

  importjavax.servlet.annotation.WebServlet;

  importjavax.servlet.http.HttpServlet;

  importjavax.servlet.http.HttpServletRequest;

  importjavax.servlet.http.HttpServletResponse;

  publicclassMVCServletextendsHttpServlet{

   privatestaticfinallongserialVersionUID=1L;

   protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

   throwsServletException,IOException{

   }

   ActionMappingManageramanager=null;

   @Override

   publicvoidinit(ServletConfigconfig)throwsServletException{

   amanager=newActionMappingManager();

   }

   protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)

   throwsServletException,IOException{

   ActionMappingam=amanager.getActionMapping(getActionName(request));

   Actionaction=ActionManager.createAction(am.getClassName());

   Stringr=action.execute(request,response);

   ResultMappingrm=am.getResults().get(r);

   if(rm.isRedirect()){

   response.sendRedirect(rm.getUrl());

   }else{

   request.getRequestDispatcher(rm.getUrl()).forward(request,response);

   }

   }

   publicStringgetActionName(HttpServletRequestrequest){

   StringactionName=null;

   Stringuri=request.getRequestURI();

   StringcontentPath=request.getContextPath();

   StringactionPath=uri.substring(contentPath.length());

   actionName=actionPath.substring(1,actionPath.indexOf(".")).trim();

   returnactionName;

   }

  }

  (十)修改web.xml

   <servlet>

   <servlet-name>MVCServlet</servlet-name>

   <servlet-class>cn.framework.MVCServlet</servlet-class>

   </servlet>

   <servlet-mapping>

   <servlet-name>MVCServlet</servlet-name>

   <url-pattern>*.action</url-pattern>

   </servlet-mapping>

  (十一)准备一个login.jsp页面   (十二)发布到Tomcat运行