一、 ???实现自定义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;
publiccla***esultMapping{
?//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运行
自定义MVC框架
原文地址:http://blog.51cto.com/13884944/2156642