天天看点

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

本节知识总结:

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

目录

本节知识总结:

一、mvc概念及思想:

二、自定义MVC演绎过程及原理

三、MVC模式和以前学习的模式(三层架构)对比:

1.几个方法写几个servlet:

2.然后就会有人用到select层,传值: 

3.反射优化 :

四、自定义MVC的实现 优化

1、中央控制器和子控制器的优化(需要用到之前的XML建模):

 2、建立模型驱动接口(实体类参数接受代码冗余):

 3、关于结果页面的跳转(转发、重定向):

一、mvc概念及思想:

MVC全称 Model View Controller,是模型(Model)-视图(View)-控制器(Controller)的缩写,是一种软件设计思想。

MVC的核心思想:将代码按照不同的作用进行划分

具体划分原则是:

Model:处理大部分的业务逻辑和数据操作JSP/HTML/freemarker

View:负责渲染数据,以html的方式呈现给用户Servlet/Action/Controller

Controller:处理用户交互,负责从视图读取数据,控制用户输入,并向模型发送数据entity、dao

作用:MVC不能提升程序执行效率,但是会提升开发效率,提高代码的重用,对于后期的更新升级具有莫大的好处

二、自定义MVC演绎过程及原理

(1)不能跨层调用;

(2)只能由上往下进行调用;View -> Controller -> Model

MVC图解:

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

 自定义MVC工作原理:

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

 注:ActionServlet-->DispatchServlet(Springmvc)

  .action         调度                         截取*(请求路径名)     处理具体业务逻辑

   JSP ---> Servlet(中央控制器)--->Action(子控制器)--->Model(Dao、DB)

三、MVC模式和以前学习的模式(三层架构)对比:

1.几个方法写几个servlet:

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

代码:

package com.xhy.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebFilter;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@WebServlet("/book/add")

public class AddBookServlet 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 {

        System.out.println("--Add增加--");

    }

}

//jsp界面

绝大多数人采用这种方法做增删改查(select层)

<a href="${pageContext.request.contextPath }/book/add" target="_blank" rel="external nofollow" >新增</a>

<a href="${pageContext.request.contextPath }/book/del" target="_blank" rel="external nofollow" >删除</a>

<a href="${pageContext.request.contextPath }/book/upd" target="_blank" rel="external nofollow" >修改</a>

<a href="${pageContext.request.contextPath }/book/list" target="_blank" rel="external nofollow" >查询</a> 

2.然后就会有人用到select层,传值: 

相交于前一种,代码量时间少的,由原来4个类变成了1个类

 缺点: 每一次新增一个方法,都要改动原有逻辑,使代码过于冗余

举例:一般当修改的时候,需要做数据回显load

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

代码:

package com.xhy.web;

import java.io.IOException;

import java.lang.reflect.Method;

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("upd".equals(methodName)){

            upd(req,resp);

        }else if("list".equals(methodName)){

            list(req,resp);

        }else if("load".equals(methodName)){

            load(req,resp);

        }

    }

    private void list(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("--查询--");

    }

    private void upd(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("--修改--");

    }

    private void del(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("--删除--");

    }

    private void add(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("--增加--");

}

//jsp界面

少数人采用这种方法做增删改查(select层)

<a href="${pageContext.request.contextPath }/book.action?methodName=add" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >新增</a>

<a href="${pageContext.request.contextPath }/book.action?methodName=del" target="_blank" rel="external nofollow" >删除</a>

<a href="${pageContext.request.contextPath }/book.action?methodName=upd" target="_blank" rel="external nofollow" >修改</a>

<a href="${pageContext.request.contextPath }/book.action?methodName=list" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >查询</a> 

3.反射优化 :

  1. 反射可以修复上面改动代码才能解决需求问题缺陷
  2. 反射这段代码,相当于中央控制器,并不直接处理浏览器请求
  3. 处理浏览器请求的是子控制器

 package com.xhy.web;

import java.io.IOException;

import java.lang.reflect.Method;

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");

        try {

            Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);

            m.setAccessible(true);

            m.invoke(this,req, resp);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    private void load(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("--回显--");    

    }

    private void ref(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("--ref--");

    }

}

//jsp界面反射优化

<a href="${pageContext.request.contextPath }/book.action?methodName=load" target="_blank" rel="external nofollow" >回显</a>

<a href="${pageContext.request.contextPath }/book.action?methodName=ref" target="_blank" rel="external nofollow" >关联查询</a> 

 1、2、3显示界面:

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

利用放射,可以修复改动代码的缺陷

反射这段代码相当于中央控制器,并不直接处理浏览器请求

处理浏览器请求的是子控制器

所以有了以下优化:

四、自定义MVC的实现 优化

1、中央控制器和子控制器的优化(需要用到之前的XML建模):

参考:XML建模

分析:

在当前中央控制器中必然会有所有子控制器集合

    //缺陷:如果有商品的增删改查-->意味着要改动代码-->代码的设计不够灵活

    //思考:在不改动代码的情况下,中央控制器也能找到对应的子控制器去处理浏览器请求

    //方案:我把加子控制器的逻辑/动作,放到配置文件中完成(Dbutil改连接信息是放在代码中完成/现在是放在Properties文件中完成)

    //放在配置文件中完成的好处在于代码更加灵活,修改相关信息不用动代码

    //ConfigModel对象又通过建模的知识,把所有的配置信息给读取过来了

    //private Map<String, ActionSupport> actions=new HashMap<>();

    //现在在xml中改

 ①浏览所需jar包:

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

 ②中央控制器DispathServlet:

package com.xhy.framework;

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;

import org.apache.commons.beanutils.BeanUtils;

@WebServlet("*.action")

public class DispatchServlet extends HttpServlet {

    private ConfigModel configModel = null;

    @Override

    public void init() throws ServletException {

        try {

            configModel = ConfigModelFactory.build();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    @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 url = req.getRequestURI();

//        url-->/book

        url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));

//        通过/book字符串在actions找到BookAction

//        ActionSupport actrion = actions.get(url);

//        在Map中寻找子控制器-->在配置文件中寻找子控制器

        ActionModel actionModel = configModel.pop(url);

//        类的全路径名

        String type = actionModel.getType();

        ActionSupport action = null;

        try {

//            BookAction/GoodsAction/..

            action = (ActionSupport) Class.forName(type).newInstance();

//            完成实体类参数的封装

            if(action instanceof ModelDriver) {

//                当前子控制器实现了模型驱动接口

                ModelDriver m = (ModelDriver) action;

//                Book/Goods/..

                Object bean = m.getModel();

//                所有的请求参数都在这,需要将所有的请求参数封装到Book/Goods/..

                BeanUtils.populate(bean, req.getParameterMap());

//                PropertyUtils.getProperty(bean, name)

            }

//            执行业务逻辑  bookAction.add方法的返回值 “list”

            String res = action.execute(req, resp);

            ForwardModel forwardModel = actionModel.pop(res);

            String path = forwardModel.getPath();

            boolean isRedirect = forwardModel.isRedirect();

            if(isRedirect) {

                resp.sendRedirect(req.getContextPath()+path);

            }else {

                req.getRequestDispatcher(path).forward(req, resp);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

config.xml :

<?xml version="1.0" encoding="UTF-8"?>

<config>

    <!-- 

        在这里每加一个配置,就相当于actions.put("/goods", new GoodsAction());

        这样就解决了代码灵活性的问题

     -->

    <action path="/book" type="com.xhy.web.BookAction">

        <forward name="list" path="/bookList.jsp" redirect="false" />//转发

        <forward name="toEdit" path="/bookEdit.jsp" redirect="true" />//重定向

    </action>

</config>

④子控制器(Action 接口):

package com.xhy.framework;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public interface Action {

    //这一个方法就是add/ref/other进行向上抽取的抽象方法

//    作用:能够处理浏览器的“所有”请求。包括add/ref/other...

    public void execute(HttpServletRequest req, HttpServletResponse resp);

}

⑤ActionSupport(实现Action):

package com.xhy.framework;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class ActionSupport implements Action {

    @Override

    public String execute(HttpServletRequest req, HttpServletResponse resp) {

        String methodName = req.getParameter("methodName");

        String res = null;

        try {

            Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

            m.setAccessible(true);

            res = (String) m.invoke(this, req, resp);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return res;

    }

}

⑥BookAction(继承ActionSupport) :

package com.xhy.web;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.xhy.entity.Book;

import com.xhy.framework.ActionSupport;

import com.xhy.framework.ModelDriver;

public class BookAction extends ActionSupport implements ModelDriver<Book>{

//    从父类继承了execute方法,就把反射动态调用方法的代码继承过来了

//    BookAction-->BookServlet

//    BookAction/GoodsAction/OrderAction...    

//    当前自动控制器在哪里调用?把子控制器与浏览器请求关联起来

    public Book book = new Book();

    private String add(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println(book);

        System.out.println("bookDao.add(book)...");

        return "list";

    }

    private void list(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.list()...");

    }

    private String toEdit(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.toEdit()...");

        return "toEdit";

    }

    private void delete(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.delete()...");

    }

    @Override

    public Book getModel() {

        return book;

    }

}

 中央控制器及子控制器优化

<a href="${pageContext.request.contextPath }/book.action?methodName=add" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >新增</a>

<a href="${pageContext.request.contextPath }/book.action?methodName=list" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >查询</a>

<a href="${pageContext.request.contextPath }/book.action?methodName=delete" target="_blank" rel="external nofollow" >删除</a>

<hr>

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化
自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

 2、建立模型驱动接口(实体类参数接受代码冗余):

①实体book类:

package com.xhy.entity;

public class Book {

    public String bid;

      public String bname;

      public String price;

      public String athor;

      public String publish;

    public String getBid() {

        return bid;

    }

    public void setBid(String bid) {

        this.bid = bid;

    }

    public String getBname() {

        return bname;

    }

    public void setBname(String bname) {

        this.bname = bname;

    }

    public String getPrice() {

        return price;

    }

    public void setPrice(String price) {

        this.price = price;

    }

    public String getAthor() {

        return athor;

    }

    public void setAthor(String athor) {

        this.athor = athor;

    }

    public String getPublish() {

        return publish;

    }

    public void setPublish(String publish) {

        this.publish = publish;

    }

    @Override

    public String toString() {

        return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + ", athor=" + athor + ", publish="

                + publish + "]";

    }

}

②DispatchServlet 中央控制器

package com.xhy.framework;

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;

import org.apache.commons.beanutils.BeanUtils;

@WebServlet("*.action")

public class DispatchServlet extends HttpServlet {

    @Override

    public void init() throws ServletException {

        try {

            configModel = ConfigModelFactory.build();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    @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 url = req.getRequestURI();

//        url-->/book

        url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));

//        通过/book字符串在actions找到BookAction

//        ActionSupport actrion = actions.get(url);

//        在Map中寻找子控制器-->在配置文件中寻找子控制器

        ActionModel actionModel = configModel.pop(url);

//        类的全路径名

        String type = actionModel.getType();

        ActionSupport action = null;

        try {

//            BookAction/GoodsAction/..

            action = (ActionSupport) Class.forName(type).newInstance();

//            完成实体类参数的封装

            if(action instanceof ModelDriver) {

//                当前子控制器实现了模型驱动接口

                ModelDriver m = (ModelDriver) action;

//                Book/Goods/..

                Object bean = m.getModel();

//                所有的请求参数都在这,需要将所有的请求参数封装到Book/Goods/..

                BeanUtils.populate(bean, req.getParameterMap());

//                PropertyUtils.getProperty(bean, name)

            }

//            执行业务逻辑  bookAction.add方法的返回值 “list”

            String res = action.execute(req, resp);

            ForwardModel forwardModel = actionModel.pop(res);

            String path = forwardModel.getPath();

            boolean isRedirect = forwardModel.isRedirect();

            if(isRedirect) {

                resp.sendRedirect(req.getContextPath()+path);

            }else {

                req.getRequestDispatcher(path).forward(req, resp);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

③、ModelDriver<T>(模型驱动接口)

package com.xhy.framework;

public interface ModelDriver<T> {

    T getModel();

}

④、 BookAction (extends ActionSupport implements ModelDriver<Book>)

package com.xhy.web;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.xhy.entity.Book;

import com.xhy.framework.ActionSupport;

import com.xhy.framework.ModelDriver;

public class BookAction extends ActionSupport implements ModelDriver<Book>{

//    从父类继承了execute方法,就把反射动态调用方法的代码继承过来了

//    BookAction-->BookServlet

//    BookAction/GoodsAction/OrderAction...    

//    当前自动控制器在哪里调用?把子控制器与浏览器请求关联起来

    public Book book = new Book();

    private String add(HttpServletRequest req, HttpServletResponse resp) {

//        book.setBid(req.getParameter("bid"));

//        book.setBname(req.getParameter("bname"));

//        book.setPrice(req.getParameter("price"));

//        book.setAthor(req.getParameter("athor"));

//        book.setPublish(req.getParameter("publish"));

        System.out.println(book);

        System.out.println("bookDao.add(book)...");

        return "list";

    }

    private void list(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.list()...");

    }

    private String toEdit(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.toEdit()...");

        return "toEdit";

    }

    private void delete(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.delete()...");

    }

    @Override

    public Book getModel() {

        return book;

    }

}

 重现参数处理代码冗余的问题

<form action="${pageContext.request.contextPath }/book.action?methodName=add" method="post">

    书籍ID:<input type="text" name="bid" value="2">

    书籍名称:<input type="text" name="bname" value="2x">

    书籍价格:<input type="text" name="price" value="2a">

    书籍作者:<input type="text" name="athor" value="2b">

    书籍出版社:<input type="text" name="publish" value="2c">

    <input type="submit">

</form>

运行结果: 

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化
自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化
自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

 3、关于结果页面的跳转(转发、重定向):

由于经常要写到类似于:

 *                 req.getdispather("/index.jsp").forward(req,resp);

 *                 resp.sendredirect("/index.jsp");

通过修改Action(子控制器)返回值viod为String:

package com.xhy.framework;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public interface Action {

    //这一个方法就是add/ref/other进行向上抽取的抽象方法

//    作用:能够处理浏览器的“所有”请求。包括add/ref/other...

//    通过返回值来决定跳转哪一个页面(至于是重定向/转发由中央控制器决定..)

    public String execute(HttpServletRequest req, HttpServletResponse resp);

}

 ActionSupport添加一个返回值:

package com.xhy.framework;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class ActionSupport implements Action {

    @Override

    public String execute(HttpServletRequest req, HttpServletResponse resp) {

        String methodName = req.getParameter("methodName");

        String res = null;

        try {

            Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

            m.setAccessible(true);

            res = (String) m.invoke(this, req, resp);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return res;

    }

}

 BookAction的返回值也要修改成String:

package com.xhy.web;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.xhy.entity.Book;

import com.xhy.framework.ActionSupport;

import com.xhy.framework.ModelDriver;

public class BookAction extends ActionSupport implements ModelDriver<Book>{

//    从父类继承了execute方法,就把反射动态调用方法的代码继承过来了

//    BookAction-->BookServlet

//    BookAction/GoodsAction/OrderAction...    

//    当前自动控制器在哪里调用?把子控制器与浏览器请求关联起来

    public Book book = new Book();

    private String add(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.add(book)...");

        return "list";

    }

    private void list(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.list()...");

    }

    private String toEdit(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.toEdit()...");

        return "toEdit";

    }

    private void delete(HttpServletRequest req, HttpServletResponse resp) {

        System.out.println("bookDao.delete()...");

    }

    @Override

    public Book getModel() {

        return book;

    }

}

举例建立bookEdit.jsp、bookList.jsp

 config.xml:

<?xml version="1.0" encoding="UTF-8"?>

<config>    

    <!-- 

        在这里每加一个配置,就相当于actions.put("/goods", new GoodsAction());

        这样就解决了代码灵活性的问题

     -->

    <action path="/book" type="com.xhy.web.BookAction">

        <forward name="list" path="/bookList.jsp" redirect="false" />//转发

        <forward name="toEdit" path="/bookEdit.jsp" redirect="true" />//重定向

    </action>

</config>

 DispatchServlet:

package com.xhy.framework;

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;

import org.apache.commons.beanutils.BeanUtils;

@WebServlet("*.action")

public class DispatchServlet extends HttpServlet {

    @Override

    public void init() throws ServletException {

        try {

            configModel = ConfigModelFactory.build();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    @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 url = req.getRequestURI();

        url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));

        ActionModel actionModel = configModel.pop(url);

        String type = actionModel.getType();

        ActionSupport action = null;

        try {

            action = (ActionSupport) Class.forName(type).newInstance();

            if(action instanceof ModelDriver) {

                ModelDriver m = (ModelDriver) action;

                Object bean = m.getModel();

                BeanUtils.populate(bean, req.getParameterMap());

            }

            String res = action.execute(req, resp);

            ForwardModel forwardModel = actionModel.pop(res);

            String path = forwardModel.getPath();

            boolean isRedirect = forwardModel.isRedirect();

            if(isRedirect) {

                resp.sendRedirect(req.getContextPath()+path);

            }else {

                req.getRequestDispatcher(path).forward(req, resp);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

解决结果码页面跳转代码冗余问题

<a href="${pageContext.request.contextPath }/book.action?methodName=add" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >新增</a>

<a href="${pageContext.request.contextPath }/book.action?methodName=toEdit" target="_blank" rel="external nofollow" >去往编辑界面</a> 

 输出结果:

自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化
自定义MVC框架本节知识总结:一、mvc概念及思想:二、自定义MVC演绎过程及原理三、MVC模式和以前学习的模式(三层架构)对比:四、自定义MVC的实现 优化

继续阅读