一.什么是MVC
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
二.编程模式
- Model(模型)表示应用程序核心(比如数据库记录列表)
- 是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中cun存取数据。
- View(视图)显示数据(数据库记录)
- 是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。
- Controller(控制器)处理输入(写入数据库记录)
- 是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
三.MVC结构
- V
- jsp
- ios
- android
- C
- servlet
- action
- M
- 实体域模型(名词)
- 过程域模型(动词)
注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 }