struts2自定义MVC框架
本文实例为大家分享了struts2自定义mvc框架的方法,供大家参考,具体内容如下
自定义mvc: (首先了解model1和model2的概念)
model1与model2:
model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起。
model2:model2是在model1的基础上,将业务逻辑的代码分离开来,单独形成一个servlet,model2也是基于mvc开发。
总结mvc特点如下:
(1)数据的获取和显示分离
(2)控制器将不同的模型和视图组合在一起
(3)应用分为三部分,三部分之间松耦合并协同工作,从而提高应用的可扩展性和可维护性
(4)各层负责不同的功能,各司其职,每一层的组件具有相同的特征,便于通过工程化和工具化产生程序代码
mvc思想及其优势(很强势)
mvc是一种架构模式,目的是将模型(业务逻辑)、视图(表示层)分离,使模型和视图可以独立修改互不影响。大多数软件在设计架构时都采用此模式。使用mvc模式有很多处,当一个通过浏览器浏览的系统想要开发手机版本时,只需要重新开发视图,模型部分的业务逻辑可以重用。许多软件需要同时推出b/s和c/s版本,采用mvc模式,模型部分可以重用,只需要开发不同的视图即可。mvc思想将一个应用分成三个基本部分m(model,模型)v(view,视图)c(controller,控制器)。其中m表示处理业务逻辑的部分,v表示显示数据和获取用户输入的部分,c类似中介,保证m和v不会直接交互。
基本步骤如下:
1.创建xml文档framework.xml
2.定义action接口
3.定义一个actionmapping类,视为action节点
4.定义actionmappingmanage类来管理actionmapping类(actions节点)
5.定义actionmanager类使用反射机制根据字符串类型的类名获取到具体的类(web.xml标签的书写)
6.编写servlet进行运行时机的控制
7.定义loginaction类进行测试
1.创建xml文档framework.xml
<!--?xml version="1.0" encoding="utf-8"?--> <!-- 定义约束文件 -->(标注) <!-- element 表示元素 --> <!-- attlist 表示属性 --> <!-- cdata 表示字符串类型 --> <!-- required 表示此属性必须的写 --> <!-- *代表多个 --> <!-- implied 表示此属性可写 --> <!-- redirect 重定向或转发 --> <!--element actions (action)--> <!--element action (result*)-->(*表示可以多个) <!--attlist action name cdata #required class cdata #required --> <!--attlist result name cdata #implied redirect (true|false) "false" --> ]> <framework> <!-- 进行测试 --> <actions> <action name="loginaction" class="cn.hq.action.loginaction"> <result name="success">success.jsp</result> <result name="login">index.jsp</result> </action> </actions> </framework>
注意:空格和<>的书写规范。
节点的层次。
2.定义action接口
注意:excute参数的书写,请求和响应。
3.定义一个actionmapping类,视为action节点(进行action节点的标签的书写)
进行封装字段和results集合的添加数据。
注意:添加数据的书写。(map集合)
4.定义actionmappingmanage类来管理actionmapping类(actions节点)
/* * action节点不止一个 * 用来来管理actionmapping类 */ public class actionmappingmanager { //actionmapping类的集合 private map<string,actionmapping> maps=new hashmap<string,actionmapping>(); public actionmapping getactionmapping(string name) { return maps.get(name); } //解析在src项目下的所有配置文件 //实例化完毕后进行解析 public actionmappingmanager(string[] file){ for (string filename : file) { init(filename); } } //init初始化方法 //解析xml文档 public void init(string path){ try { inputstream is=this.getclass().getresourceasstream("/"+path); //解析xml document doc=new saxreader().read(is); //获取根节点 element root = doc.getrootelement(); //获取actions节点 element actions=(element)root.elementiterator("actions").next(); //使用for循环来遍历actions节点下的所有action节点 for(iterator<element> action=actions.elementiterator("action");action.hasnext();) { //获取到<action>节点 element actionnext = action.next(); //分别获取到action节点中的name属性和class属性 string name = actionnext.attributevalue("name"); string classname = actionnext.attributevalue("class"); //将以上两个属性保存到actionmapping类中 actionmapping mapp=new actionmapping(); mapp.setclassname(classname); mapp.setname(name); //由于一个action节点下有多个result节点 遍历action下所有的result节点 for(iterator<element> result=actionnext.elementiterator("result");result.hasnext();) { //获取到result节点 element resultnext = result.next(); //提取result节点的name属性值和result节点中的值 string resultname = resultnext.attributevalue("name"); string resultvalue=resultnext.gettext(); //将其分别存入到actionmapping中的双列集合中去,方便调用actionmapping类(actionmapping类中就有数据了!) mapp.addresult(resultname, resultvalue); system.out.println(mapp.getname()); } //得到所有action节点的集合 maps.put(mapp.getname(), mapp); } } catch (exception e) { // todo: handle exception } } }
概括:
通过dom4j解析framework.xml配置文件。从而获取根节点,以及actions节点,并通过for循环遍历actions节点下的action节点拿到name和class的属性值,由于一个action节点下有多个result节点 及遍历action下所有的result节点,分别存入到actionmapping中的双列集合中,最后得到所有action节点的集合。
注意:init方法的书写,以及actionmappingmanager带参数组的书写。
5.定义actionmanager类使用反射机制根据字符串类型的类名获取到具体的类
public class actionmanager { public static action getactionclass(string classname) { class clazz=null; action action=null; //获取当前线程的类加载器 try { //如果线程中的有那么一个类,直接根据类名获取该类的类型 clazz=thread.currentthread().getcontextclassloader().loadclass(classname); } catch (classnotfoundexception e) { // todo auto-generated catch block e.printstacktrace(); } if(clazz==null) { try { //如果该线程中没有,那么使用class.forname方法获取 clazz=class.forname(classname); } catch (classnotfoundexception e) { // todo auto-generated catch block e.printstacktrace(); } } if(action==null) { try { //将获取到的类型转换为action,调用无参构造函数,某种程度上相当于new,不过new需要指定类型 action=(action)clazz.newinstance(); } catch (instantiationexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (illegalaccessexception e) { // todo auto-generated catch block e.printstacktrace(); } } return action; } }
web.xml的节点配置:
6.编写servlet进行运行时机的控制(servlet,初始化所有的类)
public class myservlet extends httpservlet { /** *你很菜 */ public void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { dopost(request, response); }<br> /** *继续努力 */ actionmappingmanager man=null; public void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { //获取actionmapping对象 actionmapping actionmapping = man.getactionmapping(getpath(request)); //获取action接口反射机制 action action = actionmanager.getactionmanager(actionmapping.getclassname()); try { string message=action.execute(request, response); string results = actionmapping.getresults(message); response.sendredirect(results); } catch (exception e) { // todo auto-generated catch block e.printstacktrace(); } } /* * 获取请求的路径名 */ public string getpath(httpservletrequest request){ //项目+请求地址 string requesturi = request.getrequesturi(); //项目名称 string contextpath = request.getcontextpath(); //具体请求 string path = requesturi.substring(contextpath.length()); string filename = path.substring(1,path.lastindexof(".")); return filename; } /* *重写init,程序运行加载所有类 * */ @override public void init(servletconfig config) throws servletexception { //config对象是javax.servlet.servletconfig的对象,功能是获得初始化配置信息 //config.getinitparameter是取得指定名称的初始化参数内容 string filename = config.getinitparameter("config"); string [] filenames=null; if(filename==null){ //如果为空 , filenames=new string[]{"framework.xml"}; }else{ //若果有其他的配置参数信息,那么以,分隔存入数组中 filenames=filename.split(","); } //使用init方法进行初始化 man=new actionmappingmanager(filenames); } }
注意:代码的层次及注释。
7.定义loginaction类进行测试
public class loginaction implements action{ @override public string execute(httpservletrequest request, httpservletresponse response) throws exception { string name = request.getparameter("name"); string pwd = request.getparameter("pwd"); if(name.equals("1")&&pwd.equals("1")){ return success; }else{ return login; } } }
jsp代码:
实现效果:
再长的路,一步步也能走完,再短的路,不迈开双脚也无法到达。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。