MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
编程模式
Model(模型)表示应用程序核心(比如数据库记录列表)
是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中cun存取数据。
View(视图)显示数据(数据库记录)
是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。
Controller(控制器)处理输入(写入数据库记录)
是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据
自定义mvc工作原理图
自定义mvc原理实现
其中要用到xml的建模代码,请参考:
https://www.cnblogs.com/huxiaocong/p/11015593.html
定义子控制器接口Action
用来直接处理浏览器发送过来的请求
package com.framework; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 子控制器 * @author 旧城 * */ public interface Action { String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException; }
创建实体类:
package com.entity; public class Cal { private String num1; private String num2; public String getNum1() { return num1; } public void setNum1(String num1) { this.num1 = num1; } public String getNum2() { return num2; } public void setNum2(String num2) { this.num2 = num2; } public Cal(String num1, String num2) { super(); this.num1 = num1; this.num2 = num2; } public Cal() { super(); // TODO Auto-generated constructor stub } }
创建子控制器AddCalAction(加法):
package com.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.framework.Action; public class AddCalAction implements Action{ @Override public String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String num1=req.getParameter("num1"); String num2=req.getParameter("num2"); req.setAttribute("res", Integer.valueOf(num1)+Integer.valueOf(num2)); req.getRequestDispatcher("calRes.jsp").forward(req, resp); return null; } }
减乘除只需把Integer.valueOf(num1)+Integer.valueOf(num2)中的+改为—,*, / ,即可
创建中央控制器DispatchrServlet
接收请求,通过请求寻找对应的子控制器
package com.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.web.AddCalAction; import com.web.DelCalAction; /** * 主控制器 * 专门用来处理业务逻辑 * @author 旧城 * */ public class DispatcherServlet extends HttpServlet{ private static final long serialVersionUID = 723689920988912828L; // private Map<String, Action> actionMap=new HashMap<>(); private ConfigModel configModel=null; public void init() { // actionMap.put("/addCal", new AddCalAction()); // actionMap.put("/delCal", new DelCalAction()); try { configModel=ConfigModelFactory.build(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { init(); String url=req.getRequestURI(); url=url.substring(url.lastIndexOf("/"), url.lastIndexOf(".")); ActionModel actionModel=configModel.pop(url); if(configModel==null) { throw new RuntimeException("你没有配置action标签"); } try { Action action=(Action)Class.forName(actionModel.getType()).newInstance(); action.execute(req, resp); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <config> <action path="/delCal" type="com.web.DelCalAction"> <forward name="calRes" path="/calRes.jsp" redirect="false" /> </action> <action path="/addCal" type="com.web.AddCalAction"> <forward name="calRes" path="/calRes.jsp" redirect="false" /> </action> </config>
WEB-INF文件夹下的xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>mvc_01</display-name> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>com.framework.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
创建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(val) { if(val==1){ calForm.action="${pageContext.request.contextPath }/addCal.action"; }else if(val==2){ calForm.action="${pageContext.request.contextPath }/delCal.action"; } calForm.subimt(); } </script> </head> <body> <form id="calForm" action="${pageContext.request.contextPath }/addCal.action"> 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>
<%@ 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> </head> <body> 结果: ${res } </body> </html>
运行结果:
相加:
通过XML对自定义mvc框架进行增强
中央控制器:
package com.framework; import java.io.IOException; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; 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.qukang.web.Addction; import com.qukang.web.Exceptaction; import com.qukang.web.Minusction; import com.qukang.web.Multiplication; import com.sun.org.apache.xpath.internal.operations.Mult; /** * 中央控制器 * 作用:接受请求,通过请求的对应的子控制器 * @author VULCAN * */ public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 5304895244625871732L; // 在configModel对象中包含了所有的子控制器 private ConfigModel configModel; // 一个子控制器的集合 private Map<String,Action> actionMap=new HashMap<>(); // 每次访问Servlet执行 public void init(){ // actionMap.put("/addCal",new Addction()); // actionMap.put("/delCal",new Minusction()); // actionMap.put("/mluCal",new Multiplication()); // actionMap.put("/excCal",new Exceptaction()); try { String xmlPath=this.getInitParameter("xmlPath"); if(xmlPath==null ||"".equals(xmlPath)) { configModel=ConfigModelFactory.newInstance(); }else { configModel=ConfigModelFactory.newInstance(xmlPath); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub 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); ActionModel actionModel = configModel.get(url); // 可能没有配置子控制器 所有我们需要抛一下子异常 if(actionModel ==null ) { throw new RuntimeException("你没有配置action标签,找不到对应的子控制器"); } try { String type=actionModel.getType(); Action action=(Action)Class.forName(type).newInstance(); if(action instanceof ModelDrivern) { ModelDrivern drivern=(ModelDrivern)action; Object model = drivern.getModel(); // 将jsp传过来的参数封装到实体类中的原理原理 // 代码体现 源码 // 此时的model的所有属性值都是null // 我们可以将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()); // } // 前任种树,后人乘凉 BeanUtils.populate(model, req.getParameterMap()); // 大大的减轻了代码量 } String execute = action.execute(req, resp); ForwardModel forwardModel = actionModel.get(execute); 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 (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
模型驱动接口
package com.qukang.framework; /** * 模型驱动接口 * 作用是将jsp所有传递过来的参数都自动封装到浏览器所要操作的实体类型中 * @author VULCAN * */ public interface ModelDrivern<T> { T getModel(); }
增强版的子控制器
package com.qukang.framework; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 增强版的子控制器 * 原来的子控制器只能处理一个用户的请求,有时候用户的请求时多个 ,但是都是操作同一张表,那么原有的子控制的代码编写繁琐 * 增强版的作用就是将 * 将一组的相关的操作放到一个Action中 * @author VULCAN * */ public class ActionSupport implements Action { @Override public final String execute(HttpServletRequest req, HttpServletResponse resp) { String methodName=req.getParameter("methodName"); String code =""; try { Method m=this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); code =(String) m.invoke(this,req,resp); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { } return code; } }
处理增强版子控制器传来的所有请求:
package com.qukang.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.qukang.entity.Cal; import com.qukang.framework.ActionSupport; import com.qukang.framework.ModelDrivern; import com.sun.accessibility.internal.resources.accessibility; public class CalAction extends ActionSupport implements ModelDrivern<Cal> { private Cal cal=new Cal(); public String add(HttpServletRequest req, HttpServletResponse resp){ // String num1=req.getParameter("num1"); // String num2=req.getParameter("num2"); // Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2)); req.setAttribute("sum",cal.getNum1()+cal.getNum2()); return "rs"; } public String min(HttpServletRequest req, HttpServletResponse resp){ // String num1=req.getParameter("num1"); // String num2=req.getParameter("num2"); // Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2)); req.setAttribute("sum",cal.getNum1()-cal.getNum2()); return "rs"; } public String multip(HttpServletRequest req, HttpServletResponse resp){ // String num1=req.getParameter("num1"); // String num2=req.getParameter("num2"); // Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2)); req.setAttribute("sum",cal.getNum1()*cal.getNum2()); return "rs"; } public String excep(HttpServletRequest req, HttpServletResponse resp){ // String num1=req.getParameter("num1"); // String num2=req.getParameter("num2"); // Cal cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2)); req.setAttribute("sum",cal.getNum1()/cal.getNum2()); return "rs"; } @Override public Cal getModel() { // TODO Auto-generated method stub return cal; } }
xml配置:
<?xml version="1.0" encoding="UTF-8"?> <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"> <display-name>T226_mvc</display-name> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>com.qukang.framework.DispatcherServlet</servlet-class> <init-param> <param-name>xmlPath</param-name> <param-value>/mvc3.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
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?menthodName=add"; } else if(num==2){ calForm.action="${pageContext.request.contextPath}/Cal.action?menthodName=minus"; } else if(num==3){ calForm.action="${pageContext.request.contextPath}/Cal.action?menthodName=multiply"; } else if(num==4){ calForm.action="${pageContext.request.contextPath}/Cal.action?menthodName=divided"; } calForm.submit(); } </script> </head> <body> <form name="calForm" method="post" action=""> 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>