zoukankan      html  css  js  c++  java
  • 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 重定向或转发 -->
    
    <!DOCTYPE Framework[
    
    	<!ELEMENT Framework (actions)>
    	<!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);
    	}
    /** *继续努力 */ 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代码:

    实现效果:


    再长的路,一步步也能走完,再短的路,不迈开双脚也无法到达。

                          --告诫自己

  • 相关阅读:
    数据库乐观锁应用
    maven 引入本地jar
    GTS 分布式事务
    redis 做冥等
    服务器 启动命令
    pgAdmin4的应用
    PostgreSQL 分区
    压测工具
    BigDecimal 比较大小
    移动端px转化为rem
  • 原文地址:https://www.cnblogs.com/hq-123/p/5987363.html
Copyright © 2011-2022 走看看