一. 什么是MVC?
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写, 它是一种软件设计典范。
用一种业务逻辑、数据、界面显示分离的方法,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
提高了程序的可维护性、可移植性、可扩展性与可重用性,降低了程序的开发难度。它主要分模型、视图、控制器三层。
MVC结构
模型(Model):是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。
视图(View):是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。
控制器(Controller):是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
MVC是一个框架模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。最典型的MVC就是JSP + servlet + javabean的模式。
Model:常用javabean去实现,通过各种类来对数据库的数据进行获取,并封装在对象当中。
View:常用JSP来实现,通过可直接观察的JSP页面来展示我们从数据库中获取的数据。
Controller:常用servlet来实现,通过servlet来获取经过javabean包装过的对象(已存入数据库中的数据),然后再发送数据传输到JSP界面。
MVC的不足:
1.不能跨层调用
2.只能从上往下进行调用,View-->Controller-->Model
二. 自定义MVC的运行原理
核心组件说明:
中央控制器(ActionServlet):负责接收所有的请求,并分别给控制器具体处理。
子控制器(Action):负责处理中央处理器分配的请求。
用户发送请求 → 中央控制器接受用户请求 → 分析请求连接/获取到用户需要的类+方法 → 调用相对应的Model → 访问数据库服务器
三. 自定义MVC框架与三层架构的区别
- 三层架构是基于业务逻辑来分的,而MVC是基于页面来分的;
- 三层是种软件架构,通过接口实现编程,MVC模式是一种复合设计模式,一种解决方案;
- 三层架构模式是体系结构模式,MVC是设计模式;
- 三层架构模式又可归于部署模式,MVC可归于表示模式。
四. 基础的增删改查代码实现
前端
<%@ 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> <p>最初的版本1</p> 弊端:每一张表的每一个操作,都要一个对应的servlet<br> <a href="bookadd.action">增加</a> <a href="bookdel.action">删除</a> <a href="bookupd.action">修改</a> <a href="bookquery.action">查询</a>
后台
package com.xissl.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/bookadd.action") public class BookAddServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("bookaddservlet.add..."); } }
package com.xissl.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/bookupd.action") public class BookUpdServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("bookupdservlet.upd..."); } }
package com.xissl.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/bookdel.action") public class BookDelServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("bookdelservlet.del..."); } }
package com.xissl.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/bookquery.action") public class BookQueryServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("bookqueryservlet.query..."); } }
四. 自定义MVC实现
中央控制器
并不实际处理浏览器请求,它的职责是找到对应的子控制器去处理请求
package com.xissl.framework; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.xissl.web.BookAction; /** * 中央控制器 * @author xissl * */ @WebServlet("*.action") public class DispatherServlet extends HttpServlet{ // 存放子控制器的容器 Map<String, Action> actionMap = new HashMap<String, Action>(); @Override public void init() throws ServletException { actionMap.put("/book", new BookAction()); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String url = req.getRequestURI(); url = url.substring(url.lastIndexOf("/"), url.lastIndexOf(".")); Action action = actionMap.get(url); action.execute(req, resp); } }
子控制器
具体处理请求的方法
package com.xissl.framework; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 子控制器 * 处理浏览器发送的请求的类 * @author xissl * */ public class Action { protected void execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String methodName = req.getParameter("methodName"); try { Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); method.setAccessible(true); method.invoke(this, req,resp); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
继承子控制器
package com.xissl.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.xissl.framework.Action; public class BookAction extends Action { public void add(HttpServletRequest req,HttpServletResponse resp) { System.out.println("bookaddservlet.add..."); } public void del(HttpServletRequest req,HttpServletResponse resp) { System.out.println("bookaddservlet.del..."); } public void upd(HttpServletRequest req,HttpServletResponse resp) { System.out.println("bookaddservlet.upd..."); } public void query(HttpServletRequest req,HttpServletResponse resp) { System.out.println("bookaddservlet.query..."); } }
jsp界面
<a href="book.action?methodName=add">增加</a> <a href="book.action?methodName=del">删除</a> <a href="book.action?methodName=upd">修改</a> <a href="book.action?methodName=query">查询</a>
运行结果如下: