MVC框架与增强

一.什么是MVC

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

二.编程模式

  • Model(模型)表示应用程序核心(比如数据库记录列表)
  1. 是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中cun存取数据。
  • View(视图)显示数据(数据库记录)
  1. 是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的
  • Controller(控制器)处理输入(写入数据库记录)
  1. 是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

三.MVC结构

  • V
  1. jsp
  2. ios
  3. android
  • C
  1. servlet
  2. action
  • M
  1. 实体域模型(名词)
  2. 过程域模型(动词)

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

四.自定义MVC工作原理图

五.自定义MVC原理实现(加减乘除)

子控制器接口Action

  • 用来直接处理浏览器发送过来的请求
 1 package com.mvc.framework;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 /**
10  * 子控制器
11  * 作用:用来直接处理浏览器发送过来的请求
12  * @author Administrator
13  *
14  */
15 public interface Action {
16     String  exxecute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
17 }

实体类Cal

 1 package com.mvc.entity;
 2 
 3 public class Cal {
 4 
 5     private int num1;
 6     private int num2;
 7     public int getNum1() {
 8         return num1;
 9     }
10     public void setNum1(int num1) {
11         this.num1 = num1;
12     }
13     public int getNum2() {
14         return num2;
15     }
16     public void setNum2(int num2) {
17         this.num2 = num2;
18     }
19     public Cal(int num1, int num2) {
20         super();
21         this.num1 = num1;
22         this.num2 = num2;
23     }
24     public Cal() {
25         super();
26     }
27     
28 }

子控制器AddCalAction(加)

 1 package com.mvc.web;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 import com.mvc.entity.Cal;
10 import com.mvc.framework.Action;
11 
12 public class AddCalAction implements Action{
13 
14     @Override
15     public String exxecute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
16         // TODO Auto-generated method stub
17         String num1=req.getParameter("num1");
18         String num2=req.getParameter("num2");
19 //        System.out.println(num1);
20 //        System.out.println(num2);
21         Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
22         req.setAttribute("req", cal.getNum1()+cal.getNum2());
23         req.getRequestDispatcher("res.jsp").forward(req, resp);
24         return null;
25     }
26 }

在这里减乘除只要更改

子控制器req.setAttribute("req", cal.getNum1()+cal.getNum2());
中的+为- * /则可实现减乘除,提供减法类DelCalAction 乘法类MulCalAction 除法类DivCalAction

中央控制器DispatchrServlet
  • 接收请求,通过请求寻找对应的子控制器
package com.mvc.framework;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mvc.web.AddCalAction;
import com.mvc.web.DelCalAction;
import com.mvc.web.DivCalAction;
import com.mvc.web.MulCalAction;

/**
 * 中央控制器
 * 作用:接收请求,通过请求寻找对应的子控制器
 * @author Administrator
 *
 */
public class DispatchrServlet extends HttpServlet{

    private Map<String, Action> ActionMap=new HashMap<>();

 public void init() {
  //
  ActionMap.put("/addCal", new AddCalAction());
  //
  ActionMap.put("/delCal", new DelCalAction());
  //
  ActionMap.put("/mulCal", new MulCalAction());
  //
   ActionMap.put("/divCal", new DivCalAction());
   

 }

@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 {
      // TODO Auto-generated method stub
      init();
     String url=req.getRequestURI();
      url=url.substring(url.lastIndexOf("/"),url.lastIndexOf("."));
            Action action = actionMap.get(url); 
            action.execute(req, resp);
     }


}

xml配置

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
 3   <display-name>JavaMVC</display-name>
 4   <servlet>
 5   <servlet-name>DispatchrServlet</servlet-name>
 6   <servlet-class>com.mvc.framework.DispatchrServlet</servlet-class> 
 7   </servlet>
 8   <servlet-mapping>
 9   <servlet-name>DispatchrServlet</servlet-name>
10   <url-pattern>*.action</url-pattern>
11   </servlet-mapping>
12 </web-app>

jsp页面代码

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>Insert title here</title>
 8 <script type="text/javascript">
 9       function doSub(num){
10           if (num==1) {
11               calForm.action="${pageContext.request.contextPath }/addCal.action"
12         }else if (num==2) {
13             calForm.action="${pageContext.request.contextPath }/delCal.action"
14 
15         }else if (num==3) {
16              calForm.action="${pageContext.request.contextPath }/mulCal.action"
17         }else if (num==4) {
18              calForm.action="${pageContext.request.contextPath }/divCal.action"
19 
20         }
21           calForm.submit();
22       }
23 
24 
25 </script>
26 </head>
27 <body>
28 <form name="calForm" action="" method="post">
29 num1:<input type="text" name="num1"><br>
30 num2:<input type="text" name="num2"><br>
31 <button onclick="doSub(1)">+</button>
32 <button onclick="doSub(2)">-</button>
33 <button onclick="doSub(3)">*</button>
34 <button onclick="doSub(4)">/</button>
35 </form>
36 </body>
37 </html>

运行结果

六.通过XML对自定义MVC框架进行增强

  • 将子控制器信息动态配置到mvc.xml中
  • 针对MVC框架的结果码进行处理
  • 将一组操作放到一个子控制器中
  • 利用模型驱动接口对mvc框架进行增强
  • 解决框架配置文件的冲突问题

将建模导入到com.mvc.framework中

导入jar包

将子控制器信息动态配置到mvc.xml中

6.1 中央控制器DispatchrServlet

  • 将所有子控制器都汇聚到ConfigModel
  • 配置
  • 反射实例化
 1 package com.mvc.framework;
 2 
 3 import java.io.IOException;
 4 import java.util.HashMap;
 5 import java.util.Map;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 import com.mvc.web.AddCalAction;
13 import com.mvc.web.DelCalAction;
14 import com.mvc.web.DivCalAction;
15 import com.mvc.web.MulCalAction;
16 
17 /**
18  * 中央控制器
19  * 作用:接收请求,通过请求寻找对应的子控制器
20  * @author Administrator
21  *
22  */
23 public class DispatchrServlet extends HttpServlet{
24 
25     //private Map<String, Action> ActionMap=new HashMap<>();
26     //第一次改进
27     //将所有子控制器都汇聚到ConfigModel
28     //在ConfigModel对象中包含了所有子控制器
29     private ConfigModel configModel;
30     
31     
32     public void init() {
33         try {
34             configModel=ConfigModelFactory.newInstance();
35         } catch (Exception e) {
36             // TODO Auto-generated catch block
37             e.printStackTrace();
38         }
39 //        ActionMap.put("/addCal", new AddCalAction());
40 //        ActionMap.put("/delCal", new DelCalAction());
41 //        ActionMap.put("/mulCal", new MulCalAction());
42 //        ActionMap.put("/divCal", new DivCalAction());
43     }
44     /**
45      * 
46      */
47     private static final long serialVersionUID = -7359199881120612454L;
48 
49     @Override
50     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
51         // TODO Auto-generated method stub
52     doGet(req, resp);
53     }
54     
55     @Override
56     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
57         // TODO Auto-generated method stub
58         init();
59         String url=req.getRequestURI();
60         url=url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
61         //配置
62         ActionModel actionModel = configModel.get(url);
63         if (actionModel==null) {
64             throw new RuntimeException("你没有配置action标签,找不到对应的子控制器来处理浏览器发送的请求");
65             
66         }
67         //反射实例化
68         try {
69             Action action =    (Action) Class.forName(actionModel.getType()).newInstance();
70             action.exxecute(req, resp);
71         } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
72             // TODO Auto-generated catch block
73             e.printStackTrace();
74         }
75 //        Action action=ActionMap.get(url);
76 
77         
78     }
79     
80 }

配置mvc.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2     <!--
 3         config标签:可以包含0~N个action标签
 4     -->
 5 <config>
 6     <action path="/addCal" type="com.mvc.web.AddCalAction">
 7         <forward name="rs" path="/rs.jsp" redirect="false" />
 8     </action>
 9     
10     <action path="/delCal" type="com.mvc.web.DelCalAction">
11         <forward name="rs" path="/rs.jsp" redirect="false" />
12     </action>
13     
14     <action path="/mulCal" type="com.mvc.web.MulCalAction">
15         <forward name="rs" path="/rs.jsp" redirect="false" />
16     </action>
17     
18     <action path="/divCal" type="com.mvc.web.DivCalAction">
19         <forward name="rs" path="/rs.jsp" redirect="false" />
20     </action>
21     
22 </config>

工厂模式ConfigModelFactory

 1 package com.mvc.framework;
 2 
 3 import java.io.InputStream;
 4 import java.util.List;
 5 
 6 import org.dom4j.Document;
 7 import org.dom4j.Element;
 8 import org.dom4j.io.SAXReader;
 9 
10 public class ConfigModelFactory {
11     private ConfigModelFactory() {
12 
13     }
14 
15     private static ConfigModel configModel = null;
16 
17     public static ConfigModel newInstance() throws Exception {
18         return newInstance("mvc.xml");
19     }
20 
21     /**
22      * 工厂模式创建config建模对象
23      * 
24      * @param path
25      * @return
26      * @throws Exception
27      */
28     public static ConfigModel newInstance(String path) throws Exception {
29         if (null != configModel) {
30             return configModel;
31         }
32 
33         ConfigModel configModel = new ConfigModel();
34         InputStream is = ConfigModelFactory.class.getResourceAsStream(path);
35         SAXReader saxReader = new SAXReader();
36         Document doc = saxReader.read(is);
37         List<Element> actionEleList = doc.selectNodes("/config/action");
38         ActionModel actionModel = null;
39         ForwardModel forwardModel = null;
40         for (Element actionEle : actionEleList) {
41              actionModel = new ActionModel();
42             actionModel.setPath(actionEle.attributeValue("path"));
43             actionModel.setType(actionEle.attributeValue("type"));
44             List<Element> forwordEleList = actionEle.selectNodes("forward");
45             for (Element forwordEle : forwordEleList) {
46                 forwardModel = new ForwardModel();
47                 forwardModel.setName(forwordEle.attributeValue("name"));
48                 forwardModel.setPath(forwordEle.attributeValue("path"));
49                 forwardModel.setRedirect(forwordEle.attributeValue("redirect"));
50                 actionModel.put(forwardModel);
51             }
52 
53             configModel.put(actionModel);
54         }
55 
56         return configModel;
57     }
58     
59     public static void main(String[] args) {
60         try {
61             ConfigModel configModel = ConfigModelFactory.newInstance();
62             ActionModel actionModel = configModel.get("/loginAction");
63             ForwardModel forwardModel = actionModel.get("failed");
64             System.out.println(actionModel.getType());
65             System.out.println(forwardModel.getPath());
66         } catch (Exception e) {
67             e.printStackTrace();
68         }
69     }
70 }

6.2针对MVC框架的结果码进行处理

中央控制器DispatchrServlet

  • 判断是重定向还是转发
  • 做转发的处理
 1 package com.mvc.framework;
 2 
 3 import java.io.IOException;
 4 import java.util.HashMap;
 5 import java.util.Map;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 import com.mvc.web.AddCalAction;
13 import com.mvc.web.DelCalAction;
14 import com.mvc.web.DivCalAction;
15 import com.mvc.web.MulCalAction;
16 
17 /**
18  * 中央控制器
19  * 作用:接收请求,通过请求寻找对应的子控制器
20  * @author Administrator
21  *
22  */
23 public class DispatchrServlet extends HttpServlet{
24 
25     //private Map<String, Action> ActionMap=new HashMap<>();
26     //第一次改进
27     //将所有子控制器都汇聚到ConfigModel
28     //在ConfigModel对象中包含了所有子控制器
29     private ConfigModel configModel;
30     
31     
32     public void init() {
33         try {
34             configModel=ConfigModelFactory.newInstance();
35         } catch (Exception e) {
36             // TODO Auto-generated catch block
37             e.printStackTrace();
38         }
39 //        ActionMap.put("/addCal", new AddCalAction());
40 //        ActionMap.put("/delCal", new DelCalAction());
41 //        ActionMap.put("/mulCal", new MulCalAction());
42 //        ActionMap.put("/divCal", new DivCalAction());
43     }
44     /**
45      * 
46      */
47     private static final long serialVersionUID = -7359199881120612454L;
48 
49     @Override
50     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
51         // TODO Auto-generated method stub
52     doGet(req, resp);
53     }
54     
55     @Override
56     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
57         // TODO Auto-generated method stub
58         init();
59         String url=req.getRequestURI();
60         url=url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
61         //配置
62         ActionModel actionModel = configModel.get(url);
63         if (actionModel==null) {
64             throw new RuntimeException("你没有配置action标签,找不到对应的子控制器来处理浏览器发送的请求");
65             
66         }
67         //反射实例化
68         try {
69             Action action =    (Action) Class.forName(actionModel.getType()).newInstance();
70         String code=action.exxecute(req, resp);
71         ForwardModel forwardModel = actionModel.get(code);
72         if (forwardModel!=null) {
73             String jspPath=forwardModel.getPath();
74             //判断是重定向还是转发
75             if ("false".equals(forwardModel.getRedirect())) {
76                 //做转发的处理
77                 req.getRequestDispatcher(jspPath).forward(req, resp);
78             }else {
79                 resp.sendRedirect(req.getContextPath()+jspPath);
80             }
81         }
82         } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
83             // TODO Auto-generated catch block
84             e.printStackTrace();
85         }
86 //        Action action=ActionMap.get(url);
87 
88         
89     }
90     
91 }
AddCalAction 
package com.mvc.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mvc.entity.Cal;
import com.mvc.framework.Action;

public class AddCalAction implements Action{

    @Override
    public String exxecute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        String num1=req.getParameter("num1");
        String num2=req.getParameter("num2");
//        System.out.println(num1);
//        System.out.println(num2);
        Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
        req.setAttribute("req", cal.getNum1()+cal.getNum2());
        //req.getRequestDispatcher("res.jsp").forward(req, resp);
        return "res";
    }
}

DelCalAction

 1 package com.mvc.web;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 import com.mvc.entity.Cal;
10 import com.mvc.framework.Action;
11 
12 public class DelCalAction implements Action{
13 
14     @Override
15     public String exxecute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
16         // TODO Auto-generated method stub
17         String num1=req.getParameter("num1");
18         String num2=req.getParameter("num2");
19 //        System.out.println(num1);
20 //        System.out.println(num2);
21         Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
22         req.setAttribute("req", cal.getNum1()-cal.getNum2());
23     //    req.getRequestDispatcher("res.jsp").forward(req, resp);
24         return "res";
25     }
26 
27 
28 
29 }

mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
    <!--
        config标签:可以包含0~N个action标签
    -->
<config>
    <action path="/addCal" type="com.mvc.web.AddCalAction">
        <forward name="res" path="/res.jsp" redirect="false" />
    </action>
    
    <action path="/delCal" type="com.mvc.web.DelCalAction">
        <forward name="res" path="/res.jsp" redirect="false" />
    </action>
    
    <action path="/mulCal" type="com.mvc.web.MulCalAction">
        <forward name="res" path="/res.jsp" redirect="false" />
    </action>
    
    <action path="/divCal" type="com.mvc.web.DivCalAction">
        <forward name="res" path="/res.jsp" redirect="false" />
    </action>
    
</config>

ForwardModel

 1 package com.mvc.framework;
 2 import java.io.Serializable;
 3 
 4 /**
 5  * 用来描述forward标签
 6  * @author Administrator
 7  *
 8  */
 9 public class ForwardModel implements Serializable {
10 
11     private static final long serialVersionUID = -8587690587750366756L;
12 
13     private String name;
14     private String path;
15     private String redirect;
16 
17     public String getName() {
18         return name;
19     }
20 
21     public void setName(String name) {
22         this.name = name;
23     }
24 
25     public String getPath() {
26         return path;
27     }
28 
29     public void setPath(String path) {
30         this.path = path;
31     }
32 
33     public String getRedirect() {
34         return redirect;
35     }
36 
37     public void setRedirect(String redirect) {
38         this.redirect = redirect;
39     }
40 
41 }

6.3将一组操作放到一个子控制器中

  • 对子控制器进行增强
ActionSupport增强版子控制器
 1 package com.mvc.framework;
 2 
 3 import java.io.IOException;
 4 import java.lang.reflect.InvocationTargetException;
 5 import java.lang.reflect.Method;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 /**
11  * 增强版子控制器
12  * 原来的子控制器只能一用户请求
13  * 有时候,用户请求是多个,但是都是操作同一张表,那么原有的子控制器代码编写繁琐
14  * 增强版的作用就是:将一组相关的操作放到一个Action中
15  * @author Administrator
16  *
17  */
18 public class ActionSupport implements Action {
19 
20     @Override
21     public final String exxecute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
22         // TODO Auto-generated method stub
23         String methodName=req.getParameter("methodName");
24         String code = null;
25         //class CalAction exends ActionSupport
26 //        this在这里指的是CalAction他的一个类实例
27         try {
28         Method m =    this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
29         m.setAccessible(true);
30          code = (String) m.invoke(this, req,resp);
31         } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
32             // TODO Auto-generated catch block
33             e.printStackTrace();
34         }
35         
36         return code;
37     }
38 
39 }

将加减乘除方法放入CalAction 类中并继承子控制器ActionSupport

 1 package com.mvc.web;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 import com.mvc.entity.Cal;
10 import com.mvc.framework.ActionSupport;
11 
12 public class CalAction extends ActionSupport{
13 
14     public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
15         // TODO Auto-generated method stub
16         String num1=req.getParameter("num1");
17         String num2=req.getParameter("num2");
18 //        System.out.println(num1);
19 //        System.out.println(num2);
20         Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
21         req.setAttribute("req", cal.getNum1()+cal.getNum2());
22         //req.getRequestDispatcher("res.jsp").forward(req, resp);
23         return "res";
24     }
25     
26     public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
27         // TODO Auto-generated method stub
28         String num1=req.getParameter("num1");
29         String num2=req.getParameter("num2");
30 //        System.out.println(num1);
31 //        System.out.println(num2);
32         Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
33         req.setAttribute("req", cal.getNum1()-cal.getNum2());
34     //    req.getRequestDispatcher("res.jsp").forward(req, resp);
35         return "res";
36     }
37     
38     
39     public String mul(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
40         // TODO Auto-generated method stub
41         String num1=req.getParameter("num1");
42         String num2=req.getParameter("num2");
43 //        System.out.println(num1);
44 //        System.out.println(num2);
45         Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
46         req.setAttribute("req", cal.getNum1()*cal.getNum2());
47 //        req.getRequestDispatcher("res.jsp").forward(req, resp);
48         return "res";
49     }
50     
51     public String div(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
52         // TODO Auto-generated method stub
53         String num1=req.getParameter("num1");
54         String num2=req.getParameter("num2");
55 //        System.out.println(num1);
56 //        System.out.println(num2);
57         Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
58         req.setAttribute("req", cal.getNum1()/cal.getNum2());
59 //        req.getRequestDispatcher("res.jsp").forward(req, resp);
60         return "res";
61     }
62     
63 }

mvc.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2     <!--
 3         config标签:可以包含0~N个action标签
 4     -->
 5 <config>
 6     <!--  <action path="/addCal" type="com.mvc.web.AddCalAction">-->
 7         <!--<forward name="res" path="/res.jsp" redirect="false" />-->
 8     <!--</action>-->
 9     
10     <!--<action path="/delCal" type="com.mvc.web.DelCalAction">-->
11     <!--    <forward name="res" path="/res.jsp" redirect="false" />-->
12     <!--</action>-->
13     
14     <!--<action path="/mulCal" type="com.mvc.web.MulCalAction">-->
15     <!--    <forward name="res" path="/res.jsp" redirect="false" />-->
16     <!--</action>-->
17     
18     <!--<action path="/divCal" type="com.mvc.web.DivCalAction">-->
19     <!--    <forward name="res" path="/res.jsp" redirect="false" />-->
20     <!--</action>-->
21     
22     <action path="/cal" type="com.mvc.web.CalAction">
23         <forward name="res" path="/res.jsp" redirect="false" />
24     </action>
25 </config>

cal.jsp页面更改

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>Insert title here</title>
 8 <script type="text/javascript">
 9       function doSub(num){
10           if (num==1) {
11               calForm.action="${pageContext.request.contextPath }/cal.action?methodName=add"
12         }else if (num==2) {
13             calForm.action="${pageContext.request.contextPath }/cal.action?methodName=del"
14 
15         }else if (num==3) {
16              calForm.action="${pageContext.request.contextPath }/cal.action?methodName=mul"
17         }else if (num==4) {
18              calForm.action="${pageContext.request.contextPath }/cal.action?methodName=div"
19 
20         }
21           calForm.submit();
22       }
23 
24 
25 </script>
26 </head>
27 <body>
28 <form name="calForm" action="" method="post">
29 num1:<input type="text" name="num1"><br>
30 num2:<input type="text" name="num2"><br>
31 <button onclick="doSub(1)">+</button>
32 <button onclick="doSub(2)">-</button>
33 <button onclick="doSub(3)">*</button>
34 <button onclick="doSub(4)">/</button>
35 
36 
37 </form>
38 </body>
39 </html>

6.4解决框架配置文件的冲突问题

DispatchrServlet 中央控制器加强读取xml

 1 public void init() {
 2         try {
 3             String xmlPath= this.getInitParameter("xmlPath");
 4             if (xmlPath == null || "".equals(xmlPath)) {
 5                 configModel=ConfigModelFactory.newInstance();
 6             }else {
 7                 configModel=ConfigModelFactory.newInstance(xmlPath);
 8             }
 9             
10         } catch (Exception e) {
11             // TODO Auto-generated catch block
12             e.printStackTrace();
13         }

在src下建一个Source Folder 放入一命名不同的xml

配置web.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
 3   <display-name>JavaMVC</display-name>
 4   <servlet>
 5   <servlet-name>DispatchrServlet</servlet-name>
 6   <servlet-class>com.mvc.framework.DispatchrServlet</servlet-class> 
 7   <init-param>
 8   <param-name>xmlPath</param-name>
 9   <param-value>/mvc.xml</param-value>
10   </init-param>
11   </servlet>
12   <servlet-mapping>
13   <servlet-name>DispatchrServlet</servlet-name>
14   <url-pattern>*.action</url-pattern>
15   </servlet-mapping>
16 </web-app>

6.5利用模型驱动接口对mvc框架进行增强

  • 利用ModelDrive接口对java对象赋值(反射读写属性)
ModelDrivern<T>模型驱动接口
 1 package com.mvc.web;
 2 /**
 3  * 模型驱动接口
 4  * 作用将jsp所有传递过来的参数以及参数值
 5  * 自动封装到浏览器索要操作的实体类
 6  * @author Administrator
 7  *
 8  */
 9 public interface ModelDrivern<T> {
10 
11      T getModel();
12 }
CalAction 
 1 package com.mvc.web;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 import com.mvc.entity.Cal;
10 import com.mvc.framework.ActionSupport;
11 
12 public class CalAction extends ActionSupport implements ModelDrivern<Cal>{
13 
14     private Cal cal=new Cal();
15     
16     public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
17         // TODO Auto-generated method stub
18 //        String num1=req.getParameter("num1");
19 //        String num2=req.getParameter("num2");
20 ////        System.out.println(num1);
21 ////        System.out.println(num2);
22 //        Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
23         req.setAttribute("req", cal.getNum1()+cal.getNum2());
24         //req.getRequestDispatcher("res.jsp").forward(req, resp);
25         return "res";
26     }
27     
28     public String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
29 //        // TODO Auto-generated method stub
30 //        String num1=req.getParameter("num1");
31 //        String num2=req.getParameter("num2");
32 ////        System.out.println(num1);
33 ////        System.out.println(num2);
34 //        Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
35         req.setAttribute("req", cal.getNum1()-cal.getNum2());
36     //    req.getRequestDispatcher("res.jsp").forward(req, resp);
37         return "res";
38     }
39     
40     
41     public String mul(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
42         // TODO Auto-generated method stub
43 //        String num1=req.getParameter("num1");
44 //        String num2=req.getParameter("num2");
45 ////        System.out.println(num1);
46 ////        System.out.println(num2);
47 //        Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
48         req.setAttribute("req", cal.getNum1()*cal.getNum2());
49 //        req.getRequestDispatcher("res.jsp").forward(req, resp);
50         return "res";
51     }
52     
53     public String div(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
54         // TODO Auto-generated method stub
55 //        String num1=req.getParameter("num1");
56 //        String num2=req.getParameter("num2");
57 ////        System.out.println(num1);
58 ////        System.out.println(num2);
59 //        Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
60         req.setAttribute("req", cal.getNum1()/cal.getNum2());
61 //        req.getRequestDispatcher("res.jsp").forward(req, resp);
62         return "res";
63     }
64 
65     @Override
66     public Cal getModel() {
67         // TODO Auto-generated method stub
68         return cal;
69     }
70     
71 }
DispatchrServlet 
  1 package com.mvc.framework;
  2 
  3 import java.io.IOException;
  4 import java.lang.reflect.Field;
  5 import java.lang.reflect.InvocationTargetException;
  6 import java.util.HashMap;
  7 import java.util.Map;
  8 import java.util.Map.Entry;
  9 import java.util.Set;
 10 
 11 import javax.servlet.ServletException;
 12 import javax.servlet.http.HttpServlet;
 13 import javax.servlet.http.HttpServletRequest;
 14 import javax.servlet.http.HttpServletResponse;
 15 
 16 import org.apache.commons.beanutils.BeanUtils;
 17 import org.apache.jasper.tagplugins.jstl.core.ForEach;
 18 
 19 import com.mvc.web.AddCalAction;
 20 import com.mvc.web.DelCalAction;
 21 import com.mvc.web.DivCalAction;
 22 import com.mvc.web.ModelDrivern;
 23 import com.mvc.web.MulCalAction;
 24 
 25 /**
 26  * 中央控制器
 27  * 作用:接收请求,通过请求寻找对应的子控制器
 28  * @author Administrator
 29  *
 30  */
 31 public class DispatchrServlet extends HttpServlet{
 32 
 33     //private Map<String, Action> ActionMap=new HashMap<>();
 34     //第一次改进
 35     //将所有子控制器都汇聚到ConfigModel
 36     //在ConfigModel对象中包含了所有子控制器
 37     private ConfigModel configModel;
 38     
 39     
 40     public void init() {
 41         try {
 42             configModel=ConfigModelFactory.newInstance();
 43         } catch (Exception e) {
 44             // TODO Auto-generated catch block
 45             e.printStackTrace();
 46         }
 47 //        ActionMap.put("/addCal", new AddCalAction());
 48 //        ActionMap.put("/delCal", new DelCalAction());
 49 //        ActionMap.put("/mulCal", new MulCalAction());
 50 //        ActionMap.put("/divCal", new DivCalAction());
 51     }
 52     /**
 53      * 
 54      */
 55     private static final long serialVersionUID = -7359199881120612454L;
 56 
 57     @Override
 58     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 59         // TODO Auto-generated method stub
 60     doGet(req, resp);
 61     }
 62     
 63     @Override
 64     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 65         // TODO Auto-generated method stub
 66         init();
 67         String url=req.getRequestURI();
 68         url=url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
 69         //配置
 70         ActionModel actionModel = configModel.get(url);
 71         if (actionModel==null) {
 72             throw new RuntimeException("你没有配置action标签,找不到对应的子控制器来处理浏览器发送的请求");
 73             
 74         }
 75         //反射实例化
 76         try {
 77             Action action =    (Action) Class.forName(actionModel.getType()).newInstance();
 78             //调用赋值
 79             //action就是package com.mvc.framework.CalAction;
 80             if (action instanceof ModelDrivern) {
 81                 ModelDrivern mdDrivern=(ModelDrivern) action;
 82                 //此时的model的所有属性是null的
 83                 Object model = mdDrivern.getModel();
 84                 BeanUtils.populate(model, req.getParameterMap());
 85                 //原理
 86                 //我们可以将req.getParameterMap();的值通过反射的方式将其塞进model实例
 87 //                Map<String, String[]> parameterMap = req.getParameterMap();
 88 //                Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
 89 //                Class<? extends Object> clz = model.getClass();
 90 //                for (Entry<String, String[]> entry : entrySet) {
 91 //                    Field field = clz.getField(entry.getKey());
 92 //                    field.set(model, entry.getValue());
 93 //                }
 94             }
 95             
 96         String code=action.exxecute(req, resp);
 97         ForwardModel forwardModel = actionModel.get(code);
 98         if (forwardModel!=null) {
 99             String jspPath=forwardModel.getPath();
100             //判断是重定向还是转发
101             if ("false".equals(forwardModel.getRedirect())) {
102                 //做转发的处理
103                 req.getRequestDispatcher(jspPath).forward(req, resp);
104             }else {
105                 resp.sendRedirect(req.getContextPath()+jspPath);
106             }
107         }
108         } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
109             // TODO Auto-generated catch block
110             e.printStackTrace();
111         }
112 catch (SecurityException e) {
113             // TODO Auto-generated catch block
114             e.printStackTrace();
115         } catch (InvocationTargetException e) {
116     // TODO Auto-generated catch block
117     e.printStackTrace();
118 }
119 
120         
121     }
122     
123 }
原文地址:https://www.cnblogs.com/xcn123/p/11078745.html