zoukankan      html  css  js  c++  java
  • 自定义简单算法MVC框架

     什么是MVC框架

       MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,
       它是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,其好处是将业务逻辑聚集到一个部件里面,在改进和指定个性化页面的同时不需要重新编写业务逻    辑,MVC被独特的发展起来用于映射传统的输入,处理,显示在一个业务逻辑的图形化业务界面中。

      

      核心思想:各司其职

      注1:不能跨层调用
      注2:只能出现由上而下的调用

    MVC工作原理图:

    主控制(ActionServlet)动态调用子控制器(Action)调用完成具体的业务逻辑(火车、控制台、车轨)请求、主控制器、子控制器

    具体代码如下:

    1,导入需要用到的jar包

    2、mvc.xml建模     将Action的信息配置到xml(反射实例化)

         解决了在框架代码中去改动,以便于完成客户需求,在框架中更改代码是不合理的

    mvc.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
     
    <config>
     
     
     <!-- <action path="/addCal" type="com.yuan.web.AddCalAction">
      <forward name="res" path="/res.jsp" redirect="false" />
     </action>
     
     <action path="/delCal" type="com.yuan.web.DelCalAction">
      <forward name="res" path="/res.jsp" redirect="true"/>
     </action>  -->
     
     
      <action path="/cal" type="com.yuan.web.CalAction">
      <forward name="res" path="/res.jsp" redirect="false"/>
     </action>

    </config>

    ForwardModel

    package com.yuan.framework;
    
    import java.io.Serializable;
    
    /**
     * 用来描述forward标签�
     * @author Administrator
     *
     */
    public class ForwardModel implements Serializable {
    
        private static final long serialVersionUID = -8587690587750366756L;
    
        private String name;
        private String path;
        private String redirect;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPath() {
            return path;
        }
    
        public void setPath(String path) {
            this.path = path;
        }
    
        public String getRedirect() {
            return redirect;
        }
    
        public void setRedirect(String redirect) {
            this.redirect = redirect;
        }
    
    }

    ActionModel

    package com.yuan.framework;
    
    import java.io.Serializable;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 用来描述action标签
     * @author Administrator
     *
     */
    public class ActionModel implements Serializable{
    
        private static final long serialVersionUID = 6145949994701469663L;
        
        private Map<String, ForwardModel> forwardModels = new HashMap<String, ForwardModel>();
        
        private String path;
        
        private String type;
        
        public String getPath() {
            return path;
        }
    
        public void setPath(String path) {
            this.path = path;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public void put(ForwardModel forwardModel){
            forwardModels.put(forwardModel.getName(), forwardModel);
        }
        
        public ForwardModel get(String name){
            return forwardModels.get(name);
        }
        
    }

    ConfigModel

    package com.yuan.framework;
    
    import java.io.Serializable;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 用来描述config标签
     * @author Administrator
     *
     */
    public class ConfigModel implements Serializable{
    
        private static final long serialVersionUID = -2334963138078250952L;
        
        private Map<String, ActionModel> actionModels = new HashMap<String, ActionModel>();
        
        public void put(ActionModel actionModel){
            actionModels.put(actionModel.getPath(), actionModel);
        }
        
        public ActionModel get(String name){
            return actionModels.get(name);
        }
        
    }

    ConfigModelFactory

    package com.yuan.framework;
    
    import java.io.InputStream;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    public class ConfigModelFactory {
        private ConfigModelFactory() {
    
        }
    
        private static ConfigModel configModel = null;
    
        public static ConfigModel newInstance() throws Exception {
            return newInstance("mvc.xml");
        }
    
        /**
         * 工厂模式创建config建模对象
         * 
         * @param path
         * @return
         * @throws Exception
         */
        public static ConfigModel newInstance(String path) throws Exception {
            if (null != configModel) {
                return configModel;
            }
    
            ConfigModel configModel = new ConfigModel();
            InputStream is = ConfigModelFactory.class.getResourceAsStream(path);
            SAXReader saxReader = new SAXReader();
            Document doc = saxReader.read(is);
            List<Element> actionEleList = doc.selectNodes("/config/action");
            ActionModel actionModel = null;
            ForwardModel forwardModel = null;
            for (Element actionEle : actionEleList) {
                 actionModel = new ActionModel();
                actionModel.setPath(actionEle.attributeValue("path"));
                actionModel.setType(actionEle.attributeValue("type"));
                List<Element> forwordEleList = actionEle.selectNodes("forward");
                for (Element forwordEle : forwordEleList) {
                    forwardModel = new ForwardModel();
                    forwardModel.setName(forwordEle.attributeValue("name"));
                    forwardModel.setPath(forwordEle.attributeValue("path"));
                    forwardModel.setRedirect(forwordEle.attributeValue("redirect"));
                    actionModel.put(forwardModel);
                }
    
                configModel.put(actionModel);
            }
    
            return configModel;
        }
        
        public static void main(String[] args) {
            try {
                ConfigModel configModel = ConfigModelFactory.newInstance();
                ActionModel actionModel = configModel.get("/loginAction");
                ForwardModel forwardModel = actionModel.get("failed");
                System.out.println(actionModel.getType());
                System.out.println(forwardModel.getPath());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    3、创建中央控制器

    DispatcherServlet

    package com.yuan.framework;
    
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    import javax.management.RuntimeErrorException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.beanutils.BeanUtils;
    
    import com.yuan.web.AddCalAction;
    import com.yuan.web.DelCalAction;
    
    /**
     * 中央控制器
     *   作用: 接受请求,通过请求寻找处理请求对应的子控制器。
     * @author ***
     *
     */
    public class DispatcherServlet extends HttpServlet {
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    //    private Map<String , IAction> actionMap = new HashMap<>();
        //在configModel对象中包含了所有的子控制器信息,
        private ConfigModel configModel;
        
        public void init() {
    //        actionMap.put("/addCal", new AddCalAction());
    //        actionMap.put("/delCal", new DelCalAction());
            try {
                String xmlPath = this.getInitParameter("xmlPath");
                if(xmlPath == null || "".equals(xmlPath)){
                    configModel  = ConfigModelFactory.newInstance();
                }
                else {
                    configModel  = ConfigModelFactory.newInstance(xmlPath);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req, resp);
            
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            init();
            String url= req.getRequestURI();
    //        /项目名/addCal.action
            url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
    //        IAction action = actionMap.get(url);
            ActionModel actionModel = configModel.get(url);
            if(actionModel == null) {
                throw new RuntimeException("你没有配置action标签,找不到对应的子控制器来处理浏览器发送的请求");
                
            }
            
            try {
                
                IAction action = (IAction) Class.forName(actionModel.getType()).newInstance();
                
                //此时的action就是com.yuan.web.CalAction
                if(action instanceof ModelDrivern) {
                    ModelDrivern  drivern = (ModelDrivern) action;
                    //此时的model的所有属性值是null的
                    Object model = drivern.getModel(); 
                    
                    BeanUtils.populate(model, req.getParameterMap());
                
                    //我们可以将req.getParameterMap()的值通过反射的方式将其塞进model实例中 (源码)
    //                Map<String, String[]> parameterMap = req.getParameterMap();
    //                Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
    //                Class<? extends Object> clz = model.getClass();
    //                for (Entry<String, String[]> entry : entrySet) {
    //                    Field field = clz.getField(entry.getKey());
    //                    field.setAccessible(true);
    //                    field.set(model, entry.getValue());
    //                }
    
                }
                
                String code = action.execute(req, resp);
                ForwardModel forwardModel = actionModel.get(code);
                if(forwardModel!=null) {
                    String jspPath = forwardModel.getPath();
                    if("false".equals(forwardModel.getRedirect())) {
                        //做转发的处理
                        req.getRequestDispatcher(jspPath).forward(req, resp);
                    }else {
                        resp.sendRedirect(req.getContextPath()+jspPath);
                    }
                }
                
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | SecurityException | InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    //        action.execute(req, resp);
        }
        
    }

    web.xml配置

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>com.yuan.framework.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>xmlPath</param-name>
          <param-value>/mvc.xml</param-value>
        </init-param>
        
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.action</url-pattern>
      </servlet-mapping>

    4、一个增强版的子控制器(ActionSupport)实现简单的子控制器(IAction)

    IAction(接口)

    package com.yuan.framework;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 子控制器
     *   作用:用来直接处理浏览器发送过来的请求。
     * @author **
     *
     */
    public interface IAction {
        
     String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
     
     
    }

    ActionSupport      通过结果码控制页面的跳转,减少了逻辑层中的页面跳转代码重复性

    package com.yuan.framework;
    
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 增强版子控制器 
     *  原来的子控制器只可以处理一个请求,
     *  有时候用户请求是多个,但是都是操作同一张表,那么原有的子控制器代码编写繁琐。
     *  增强版的作用就是将一组相关的操作放到一个IAction中(子控制器)。
     * @author **
     *
     */
    public class ActionSupport implements IAction {
    
        @Override
        public final String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String methodName= req.getParameter("methodName");
            String code = null;
            //this在这里指的是CalAction它的一个类实例
            try {
                Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
                m.setAccessible(true);
                code = (String) m.invoke(this, req,resp);
            } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                e.printStackTrace();
            }
            
            
            return code;   
    } }

    5、业务逻辑层      将一组相关的操作放到一个Action中(反射调用方法)

    CalAction

    package com.yuan.web;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.entity.Cal;
    import com.yuan.framework.ActionSupport;
    import com.yuan.framework.ModelDrivern;
    
    public class CalAction extends ActionSupport implements ModelDrivern<Cal> {
    
        private Cal cal = new Cal();
        
        public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        String num1 = req.getParameter("num1");
    //        String num2 = req.getParameter("num2");
    //        Cal cal = new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
            req.setAttribute("res", cal.getNum1()- cal.getNum2());
    //        req.getRequestDispatcher("res.jsp").forward(req, resp);            
            return "res";
        }
        
        
        public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        String num1 = req.getParameter("num1");
    //        String num2 = req.getParameter("num2");
    //        Cal cal = new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
            req.setAttribute("res", cal.getNum1()+cal.getNum2());
    //        req.getRequestDispatcher("res.jsp").forward(req, resp);
            
            return "res";
        }
        
        public String chen(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        String num1 = req.getParameter("num1");
    //        String num2 = req.getParameter("num2");
    //        Cal cal = new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
            req.setAttribute("res", cal.getNum1()*cal.getNum2());
    //        req.getRequestDispatcher("res.jsp").forward(req, resp);
            
            return "res";
        }
        
        
        public String chu(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        String num1 = req.getParameter("num1");
    //        String num2 = req.getParameter("num2");
    //        Cal cal = new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
            req.setAttribute("res", cal.getNum1()/cal.getNum2());
    //        req.getRequestDispatcher("res.jsp").forward(req, resp);
            
            return "res";
        }
    
    
        @Override
        public Cal getModel() {
            
            return cal;
        }
        
        
    }

    6、创建一个模型接口       利用ModelDriver接口对Java对象进行赋值(反射读写属性),剪掉了逻辑层的获取jsp页面传值的代码重复性

    package com.yuan.framework;
    
    
    /**
     * 模型驱动接口
     *   作用:将jsp页面所有传递过来的参数以及参数值
     *   都自动封装到浏览器所要操作的实体类中,
     * @author **
     *
     */
    public interface ModelDrivern<T> {
    
        T getModel();
        
    }

    7、Cal 实体类

    package com.entity;
    
    public class Cal {
    
        private int num1;
        private int num2;
        public int getNum1() {
            return num1;
        }
        public void setNum1(int num1) {
            this.num1 = num1;
        }
        public int getNum2() {
            return num2;
        }
        public void setNum2(int num2) {
            this.num2 = num2;
        }
        public Cal(int num1, int num2) {
            super();
            this.num1 = num1;
            this.num2 = num2;
        }
        public Cal() {
            super();
            // TODO Auto-generated constructor stub
        }
     
    }

    8、jsp页面代码

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    <script type="text/javascript">
      function doSub(num){
          if(num==1){
              calForm.action = "${pageContext.request.contextPath }/cal.action?methodName=add";
          }else if(num==2){
              calForm.action = "${pageContext.request.contextPath }/cal.action?methodName=del";
          }
          else if(num==3){
              calForm.action = "${pageContext.request.contextPath }/cal.action?methodName=chen";
          }
          else if(num==4){
              calForm.action = "${pageContext.request.contextPath }/cal.action?methodName=chu";
          }
          calForm.submit();
      }
    </script>
    </head>
    <body>
    <form name="calForm" action="" method="post">
    num1:<input type="text" name="num1"> <br>
    num2:<input type="text" name="num2"> <br>
        <button onclick="doSub(1)">+</button>
        <button onclick="doSub(2)">-</button>
        <button onclick="doSub(3)">*</button>
        <button onclick="doSub(4)">/</button>
    
    </form>
    
    </body>
    </html>

    9、运行结果:

    谢谢观看^-^     !!!

  • 相关阅读:
    Android ViewPager用法小结
    HDU1212 Big Number 【同余定理】
    1051. Pop Sequence (25)
    FFmpeg源码结构图
    oracle访问不同用户的表不添加用户名前缀
    window7开启Administrator账户
    Window下对nodejs多版本管理GNVM
    基于Centos7.5搭建Docker环境
    grep与孪生兄弟egrep差异
    Linux编译步骤概述
  • 原文地址:https://www.cnblogs.com/ly-0919/p/11090884.html
Copyright © 2011-2022 走看看