目录
MVC全称名是Model(模型层) View(视图层) controller(控制层),它们分工明确,各司其职,同时也具有高类聚,低耦合的特点。
节省时间和代码。
比如说:我们在写一个项目时,都是从无到有的,创建的过程要写好多代码,还要花费好多时间。所以我们会写一个MVC来继承它,从而得到通用的效果,以至于有更多的时间与精力去完成自己的项目。
当我们自己项目要去写这么多servlet以及dao包中的方法时,往往都会出现一个共同的问题,那就是代码思路基本重复,从而就诞生了自定义MVC。
我们以书本的增删改查为例,先回顾一下最初是怎样部署代码的:






然后我们运行demo1.jsp界面,得到如下效果:

接着分别点击增加、删除、修改、查询的按钮,打印结果如下:

以上就是我们最初的增删改查,那么会存在哪些问题呢?
- package com.ycx.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("/book.action")
- public class BookServlet extends HttpServlet{
- @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 {
- // 为了区分当前请求的目的,增删改查的目的,就从前台将要调用的方法名传递到后台
- String methodName = req.getParameter("methodName");
- if("add".equals(methodName)) {
- // 如果前台传递到后台的是一个新增的请求,那么后台就新增方法
- add(req,resp);
- }else if("del".equals(methodName)){
- del(req,resp);
- }else if("edit".equals(methodName)){
- edit(req,resp);
- }else if("list".equals(methodName)){
- list(req,resp);
- }
- }
-
- private void list(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 list 方法");
- }
-
- private void edit(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 edit 方法");
- }
-
- private void del(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 del 方法");
- }
-
- private void add(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 add 方法");
- }
- }
- <h3>类数量过多问题的优化</h3>
- <a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
- <a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
控制台运行结果:

- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // 为了区分当前请求的目的,增删改查的目的,就从前台将要调用的方法名传递到后台
- String methodName = req.getParameter("methodName");
- // methodName可能是多种方法
-
- // 前台传递什么方法就调用当前类的对应方法
- try {
- Method m=this.getClass()// BookServlet.Class
- .getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
- m.setAccessible(true);
- // 调用当前类实例的 methodName 方法
- m.invoke(this, req,resp);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- private void load(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 load 方法");
- }
<a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>

控制台运行结果如下:


一样也可以调用到:

但是又会存在什么问题呢?
注意看:

所以面临第三、四个问题:

- package com.ycx.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.ycx.web.BookAction;
-
- /**
- * 中央控制器:
- * 主要职能:接收浏览器请求,找到对应的处理人
- * @author 杨总
- *
- */
- @WebServlet("*.action")
- public class DispatcherServlet extends HttpServlet{
- private Map<String, Action> actions=new HashMap<String, Action>();
-
- // 程序启动时,只会加载一次
- @Override
- public void init() throws ServletException {
- actions.put("/book", new BookAction());
- // actions.put("/order", new BookAction());
- }
-
- @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 {
- //http:localhost:8080/mvc/book.action?methodName=list
- String uri=req.getRequestURI();
- // 拿到/book,就是最后一个“/”到最后一个“.”为止
- uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
- Action action = actions.get(uri);
- action.execute(req, resp);
- }
- }
注意:其中有一个初始化init方法:



就生成了一个init初始化方法:

- package com.ycx.framework;
-
- import java.lang.reflect.Method;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- public class ActionSupport implements Action{
-
- @Override
- public void execute(HttpServletRequest req, HttpServletResponse resp) {
- String methodName = req.getParameter("methodName");
- // methodName可能是多种方法
- // 前台传递什么方法就调用当前类的对应方法
- try {
- Method m=this.getClass()// BookServlet.Class
- .getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
- m.setAccessible(true);
- // 调用当前类实例的 methodName 方法
- m.invoke(this, req,resp);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- package com.ycx.framework;
-
- import java.io.IOException;
-
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- /**
- * 子控制器:
- * 对应请求的处理人
- * @author 杨总
- *
- */
- public interface Action {
- void execute(HttpServletRequest req, HttpServletResponse resp);
- }
在com.ycx.web包内添加一个BookAction类:
- package com.ycx.web;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import com.ycx.framework.Action;
- import com.ycx.framework.ActionSupport;
-
- public class BookAction extends ActionSupport {
-
- private void load(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 load 方法");
- }
-
- private void list(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 list 方法");
- }
-
- private void edit(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 edit 方法");
- }
-
- private void del(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 del 方法");
- }
-
- private void add(HttpServletRequest req, HttpServletResponse resp) {
- System.out.println("在同一个servlet中调用 add 方法");
- }
-
- }
-
部署完毕之后,我们开始运行
比如点击书籍的删除和增加按钮,控制台打印结果如下:

我们的mvc原理就根据原理图以代码的形式呈现出来啦 ~
今日分享就到这里啦~再会!