目录
一、MVC概念描述
1、什么是MVC?
2、什么是自定义MVC?
3、自定义MVC有什么用(主要用途)?
二、MVC三层架构
第一种版本
JSP页面
servlet
结果
第二种版本
JSP代码
servlet
结果
第三种版本
jsp页面
servlet
结果
三、自定义MVC框架的雏形
工作原理图
类的创建
实践:第四种版本
jsp代码
debug测试
结果
帮助
四、利用XML建模反射优化(第五种)
示例
优化
五、优化方法调用结果集跳转问题
六、优化参数封装
实操
优化
编写一个模型驱动接口
DispatherServlet:中央处理器优化
帮助
MVC是一种设计模式,用于开发软件应用程序。它将应用程序分为三个核心部分:模型(Model)、视图(View)和控制器(Controller)。
- 模型(Model)是应用程序的数据和业务逻辑层。它负责处理数据的读取、存储、更新和删除,以及定义业务规则和逻辑。
- 视图(View)是用户界面的呈现层,负责展示数据给用户,并接收用户的输入。视图通常是用户可以看到和与之交互的界面元素,如图形界面、网页或移动应用程序的界面。
- 控制器(Controller)是模型和视图之间的中介,负责处理用户的输入、控制数据的流动以及调度视图的更新。它接收来自用户界面的输入,然后通过更新模型或通知视图来响应这些输入。
MVC的目标是将应用程序的逻辑和用户界面分离,使得代码更容易维护、修改和测试。通过将应用程序的不同部分分隔开来,可以提高代码的可读性、可扩展性和可重用性。
自定义MVC是指根据特定项目的需求和规模,自行设计和实现的MVC架构。传统的MVC架构提供了一种通用的模式来组织应用程序,但在特殊情况下,可能需要根据项目的特定需求,做一些定制化的调整或扩展。
自定义MVC使开发团队能够根据项目的需要,灵活地定义模型、视图和控制器的职责以及它们之间的通信机制。可以根据具体业务需求来调整模型和控制器的逻辑,设计符合项目需求的视图层。这样能够更好地满足项目的特殊要求,提高开发效率和代码质量。
在自定义MVC中,开发人员可以自由选择和设计使用的技术和工具,并根据项目的需要来决定是否引入其他架构模式或设计模式。这样可以根据具体的场景,综合考虑各种因素,选择最适合项目需求的架构方案。
自定义MVC是根据项目需求和规模设计的定制化MVC架构,能够更好地满足特定项目的要求,并提高开发效率和代码质量。
自定义MVC提供了灵活性、可定制化、代码组织和可维护性、可测试性、适应性和扩展性以及提高开发效率等多个方面的优势,使开发团队能够更好地满足项目的需求并提高开发质量。
第一种方式是有弊端的:
比如:你的每一个操作都需要编一个servlet类来处理
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
index
第一种
增加
删除
修改
查询
第二种
增加
删除
修改
查询
第三种
增加
删除
修改
查询
我们可以利用重定向跳转到首页,这样可以更好的给我们一个体验
response.sendRedirect("index.jsp");
package com.tgq.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;
/**
*
* @author tgq
*
*/
@WebServlet("/BookAddServlet")
public class BookAddServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("BookAddServlet");
//利用重定向跳转到首页
response.sendRedirect("index.jsp");
}
}
以此我们编写四个一样的servlet
我们依次点击增加===》删除===》修改===》查询
打印结果
弊端:虽然每一个对应每一个操作,只要写一个servlet来处理,但是每增加一个操作,都需要改变原有的代码块
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
index
第一种
增加
删除
修改
查询
第二种
增加
删除
修改
查询
第三种
增加
删除
修改
查询
package com.tgq.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;
/**
*
* @author tgq
*
*/
@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String methodName = request.getParameter("methodName");
if (methodName.equals("add")) {
add(request, response);
} else if (methodName.equals("del")) {
del(request, response);
} else if (methodName.equals("update")) {
update(request, response);
} else if (methodName.equals("list")) {
list(request, response);
}
response.sendRedirect("index.jsp");
}
private void list(HttpServletRequest request, HttpServletResponse response) {
System.out.println("list");
}
private void update(HttpServletRequest request, HttpServletResponse response) {
System.out.println("update");
}
private void del(HttpServletRequest request, HttpServletResponse response) {
System.out.println("del");
}
private void add(HttpServletRequest request, HttpServletResponse response) {
System.out.println("add");
}
}
我们依次点击增加===》删除===》修改===》查询
输出结果:
弊端:
虽然解决了if条件分支代码冗余的问题,但是放在项目范围内,反射的代码时重复的
根据以上两种,我们进行一个优化修改
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
index
第一种
增加
删除
修改
查询
第二种
增加
删除
修改
查询
第三种
增加
删除
修改
查询
package com.tgq.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;
/**
*
* @author tgq
*
*/
@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String methodName = request.getParameter("methodName");
try {
// 利用反射调用方法
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,
HttpServletResponse.class);
// 打开访问权限
method.setAccessible(true);
// 操作以下的代码不发生任何变化
method.invoke(this, request, response);
} catch (Exception e) {
e.printStackTrace();
}
response.sendRedirect("index.jsp");
}
private void list(HttpServletRequest request, HttpServletResponse response) {
System.out.println("list");
}
private void update(HttpServletRequest request, HttpServletResponse response) {
System.out.println("update");
}
private void del(HttpServletRequest request, HttpServletResponse response) {
System.out.println("del");
}
private void add(HttpServletRequest request, HttpServletResponse response) {
System.out.println("add");
}
}
我们依次点击增加===》删除===》修改===》查询
输出结果:
我们需要新建一个包framework,在这个包下面我们新建两个类Class(DispatherServlet、Action)。
在我们原本的包下面新建一个类Class(BookAction)
DispatherServlet:对应图中ActionServlet:中央处理器。
(需要继承HttpServlet:需要拦截所有的.action请求)
Action:子控制器,真正做事处理浏览器发送的请求类。
BookAction:需要继承Action
我们需要拿到我们请求的servlet的url,我们再把他截取下来。
需要一个容器来保存public Map
actionMaps = new HashMap (); 利用init()方法初始化加载,添加进map集合保存
package com.tgq.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.tgq.web.BookAction;
/**
* 对应图中ActionServlet:中央处理器
*
* @author tgq
*
*/
@WebServlet("/*.action")
public class DispatherServlet extends HttpServlet {
public Map actionMaps = new HashMap();
@Override
public void init() throws ServletException {
actionMaps.put("/BookServlet", new BookAction());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 拿到url路径
String uri = request.getRequestURI();
// 拿到路径进行一个截取,拿到最后一个“/”到最后一个“.”之间的字符串
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
Action action = actionMaps.get(uri);
}
}
我们的反射代码需要写在Action 。
package com.tgq.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 tgq
*
*/
public class Action {
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String methodName = request.getParameter("methodName");
try {
// 利用反射调用方法
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,
HttpServletResponse.class);
// 打开访问权限
method.setAccessible(true);
// 操作以下的代码不发生任何变化
method.invoke(this, request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
我们把需要调用的方法写在BookAction
package com.tgq.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tgq.framework.Action;
public class BookAction extends Action {
public void add(HttpServletRequest request, HttpServletResponse response) {
System.out.println("add");
}
public void list(HttpServletRequest request, HttpServletResponse response) {
System.out.println("list");
}
public void update(HttpServletRequest request, HttpServletResponse response) {
System.out.println("update");
}
public void del(HttpServletRequest request, HttpServletResponse response) {
System.out.println("del");
}
}
最后我们在到我们的DispatherServlet,调用方法action.execute(request, response);
这就是我们的第四个版本:解决代码重复的问题
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
index
第一种
增加
删除
修改
查询
第二种
增加
删除
修改
查询
第三种
增加
删除
修改
查询
第四种
增加
删除
修改
查询
进行一个断点测试
我们依次点击增加===》删除===》修改===》查询
我们可以看到的断点的地方已经出现我们想要的结果了,走完之后就会调用
action.execute(request, response);
我们到action里面的这里打个断点,可以看到我们想要的结果了。最后跳进我们BookAction里面的方法
如果想想我一样可以像这样建包、类等
查询必须转发,增删改只用重定向
弊端:中央控制器中的action容器加载不可以灵活配置
我们再次添加一个Order的事件,首先我们在web包里面新建一个OrderAction
package com.tgq.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.tgq.framework.Action;
public class OrderAction extends Action {
public void add(HttpServletRequest request, HttpServletResponse response) {
System.out.println("OrderAction.add...");
}
public void list(HttpServletRequest request, HttpServletResponse response) {
System.out.println("OrderAction.list...");
}
public void update(HttpServletRequest request, HttpServletResponse response) {
System.out.println("OrderAction.update...");
}
public void del(HttpServletRequest request, HttpServletResponse response) {
System.out.println("OrderAction.del...");
}
}
我们在framework包里面的DispatherServlet里面init()方法里面新写一个
actionMaps.put("/Order", new OrderAction());
package com.tgq.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.tgq.web.BookAction;
import com.tgq.web.OrderAction;
/**
* 对应图中ActionServlet:中央处理器
*
* @author tgq
*
*/
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
public Map actionMaps = new HashMap();
@Override
public void init() throws ServletException {
actionMaps.put("/Book", new BookAction());
actionMaps.put("/Order", new OrderAction());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 拿到url路径
String uri = request.getRequestURI();
// 拿到路径进行一个截取,拿到最后一个“/”到最后一个“.”之间的字符串
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
Action action = actionMaps.get(uri);
action.execute(request, response);
}
}
我们在jsp页面也编写一下事件
第五种
Book
增加
删除
修改
查询
Order
增加
删除
修改
查询
我们点击Order的删除
我们的framework是要导成jar包的,如果不可能在
@Override public void init() throws ServletException { actionMaps.put("/Book", new BookAction()); actionMaps.put("/Order", new OrderAction()); }
方法里面经常改,所以我们要用到xml
我们再在同一路径下新建Source Folder 文件夹取名conf在这个文件夹下面放入我们的xml文件
我们以前的子控制器是写在map集合里的,现在的子控制器实在mvc.xml里面,就是放在configModel里面
我们在DispatherServlet进行一个修改
package com.tgq.framework;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.management.RuntimeErrorException;
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.tgq.framework.model.ActionModel;
import com.tgq.framework.model.ConfigModel;
import com.tgq.framework.model.ConfigModelFactory;
import com.tgq.web.BookAction;
import com.tgq.web.OrderAction;
/**
* 对应图中ActionServlet:中央处理器
*
* @author tgq
*
*/
@WebServlet("/*.action")
public class DispatherServlet extends HttpServlet {
// public Map actionMaps = new HashMap();
// 原来所有的子控制器是写在map集合里面,现在是写在mvc.xml文件里,也就是configModel里面
private ConfigModel configModel;
@Override
public void init() throws ServletException {
try {
// 包含了所有的子控制器
configModel = ConfigModelFactory.bulid();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// actionMaps.put("/Book", new BookAction());
// actionMaps.put("/Order", new OrderAction());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 拿到url路径
String uri = request.getRequestURI();
// 拿到路径进行一个截取,拿到最后一个“/”到最后一个“.”之间的字符串
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// Action action = actionMaps.get(uri);
// 通过uri=/book,在configModel对象中找
ActionModel actionModel = configModel.pop(uri);
// actionModel如果==null给个提示
if (actionModel == null)
throw new RuntimeException("action not config");
// 拿到我们的路径
String type = actionModel.getType();
// 反射
try {
Action action;
action = (Action) Class.forName(type).newInstance();// =BookAction bookAction=new BookAction();
action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果
我们在BookAction里面的del()方法里面添加一个Attribute和重定向
request.setAttribute("content", "哈喽"); response.sendRedirect("res.jsp");
我们新建一个res.jsp的界面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
res 跳转成功:参数${content }我们点击jsp界面的删除
输出结果:
我们省掉
response.sendRedirect("res.jsp"); request.getRequestDispatcher("res.jsp").forward(request, response);
去Action把execute()方法的返回值改成String,BookAction里面方法的返回值也改成String
,注释掉
//response.sendRedirect("res.jsp"); //request.getRequestDispatcher("res.jsp").forward(request, response);
Action中的execute()方法优化
package com.tgq.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 tgq * */ public class Action { public String execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String methodName = request.getParameter("methodName"); String res = ""; try { // 利用反射调用方法 Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); // 打开访问权限 method.setAccessible(true); // 操作以下的代码不发生任何变化 res = (String) method.invoke(this, request, response); } catch (Exception e) { e.printStackTrace(); } return res; } }
我们在DispatherServlet里面进行一个大的优化
package com.tgq.framework; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.management.RuntimeErrorException; 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.tgq.framework.model.ActionModel; import com.tgq.framework.model.ConfigModel; import com.tgq.framework.model.ConfigModelFactory; import com.tgq.framework.model.ForwardModel; import com.tgq.web.BookAction; import com.tgq.web.OrderAction; /** * 对应图中ActionServlet:中央处理器 * * @author tgq * */ @WebServlet("/*.action") public class DispatherServlet extends HttpServlet { // public Map
actionMaps = new HashMap (); // 原来所有的子控制器是写在map集合里面,现在是写在mvc.xml文件里,也就是configModel里面 private ConfigModel configModel; @Override public void init() throws ServletException { try { // 包含了所有的子控制器 configModel = ConfigModelFactory.bulid(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // actionMaps.put("/Book", new BookAction()); // actionMaps.put("/Order", new OrderAction()); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 拿到url路径 String uri = request.getRequestURI(); // 拿到路径进行一个截取,拿到最后一个“/”到最后一个“.”之间的字符串 uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf(".")); // Action action = actionMaps.get(uri); // 通过uri=/book,在configModel对象中找 ActionModel actionModel = configModel.pop(uri); // actionModel如果==null给个提示 if (actionModel == null) throw new RuntimeException("action not config"); // 拿到我们的路径 String type = actionModel.getType(); // 反射 try { // 具体业务代码执行后的返回值 add、update、del、list返回值===toList/list Action action = (Action) Class.forName(type).newInstance();// =BookAction bookAction=new BookAction(); String execute = action.execute(request, response); // 要通过返回值拿到该方法结果是重定向还是转发,还是跳转哪个页面 ForwardModel forwardModel = actionModel.pop(execute); if (forwardModel != null) { boolean redirect = forwardModel.isRedirect(); // 拿到路径path String path = forwardModel.getPath(); // 判断增删改重定向 if (redirect) { // 加上request.getContextPath(),不然找不到项目路径 response.sendRedirect(request.getContextPath() + "/" + path); } else { request.getRequestDispatcher(request.getContextPath() + "/" + path).forward(request, response); } } } catch (Exception e) { e.printStackTrace(); } } }
弊端 :jsp传递到后台,封装到实体类的代码过多
第六种
Book
增加
我们常常传递数据的时候是用
public String add(HttpServletRequest request, HttpServletResponse response) throws Exception { String bid = request.getParameter("bid"); String bname = request.getParameter("bname"); String price = request.getParameter("price"); Book book = new Book(); book.setBid(Integer.parseInt(bid)); book.setBname(bname); book.setPrice(Float.parseFloat(price)); System.out.println("BookAction.add..."); request.setAttribute("content", "哈喽"); // response.sendRedirect("res.jsp"); return "toList"; }
这种方法传递的,最后添加到数据库里面去。写在我们进行一个优化。
我们利用
Map
parameterMap = request.getParameterMap(); 进行一个保存。
- 要有表对应的类属性对象 Book book
- 获取到所有的参数 及参数 req.getParameterMap();
- 将参数值封装到表对应的对象中
- 要做到所有子控制器通用
package com.tgq.framework;
/**
* 模型驱动接口 Book book = new Book();
*
* @author L
*
* @param
*/
public interface ModelDriver {
T getModel();
}
实现ModelDriver接口肯定会重写getModel()方法,我们返回book
package com.tgq.framework;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.management.RuntimeErrorException;
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;
import com.tgq.framework.model.ActionModel;
import com.tgq.framework.model.ConfigModel;
import com.tgq.framework.model.ConfigModelFactory;
import com.tgq.framework.model.ForwardModel;
import com.tgq.web.BookAction;
import com.tgq.web.OrderAction;
/**
* 对应图中ActionServlet:中央处理器
*
* @author tgq
*
*/
@WebServlet("/*.action")
public class DispatherServlet extends HttpServlet {
// public Map actionMaps = new HashMap();
// 原来所有的子控制器是写在map集合里面,现在是写在mvc.xml文件里,也就是configModel里面
private ConfigModel configModel;
@Override
public void init() throws ServletException {
try {
// 包含了所有的子控制器
configModel = ConfigModelFactory.bulid();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// actionMaps.put("/Book", new BookAction());
// actionMaps.put("/Order", new OrderAction());
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 拿到url路径
String uri = request.getRequestURI();
// 拿到路径进行一个截取,拿到最后一个“/”到最后一个“.”之间的字符串
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// Action action = actionMaps.get(uri);
// 通过uri=/book,在configModel对象中找
ActionModel actionModel = configModel.pop(uri);
// actionModel如果==null给个提示
if (actionModel == null)
throw new RuntimeException("action not config");
// 拿到我们的路径
String type = actionModel.getType();
// 反射
try {
// 具体业务代码执行后的返回值 add、update、del、list返回值===toList/list
Action action = (Action) Class.forName(type).newInstance();// =BookAction bookAction=new BookAction();
// 判断BookAction有没有ModelDriver接口
if (action instanceof ModelDriver) {
// 转型
ModelDriver md = (ModelDriver) action;
Object bean = md.getClass();
Map map = request.getParameterMap();
BeanUtils.populate(bean, map);
}
String execute = action.execute(request, response);
// 要通过返回值拿到该方法结果是重定向还是转发,还是跳转哪个页面
ForwardModel forwardModel = actionModel.pop(execute);
if (forwardModel != null) {
boolean redirect = forwardModel.isRedirect();
// 拿到路径path
String path = forwardModel.getPath();
// 判断增删改重定向
if (redirect) {
// 加上request.getContextPath(),不然找不到项目路径
response.sendRedirect(request.getContextPath() + "/" + path);
} else {
request.getRequestDispatcher(request.getContextPath() + "/" + path).forward(request, response);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
在这个里面
BeanUtils.populate(bean, map);
已经替代了
Set
> entrySet = map.entrySet(); for (Entry entry : entrySet) { entry.getKey(); }
我么进行一个断点测试,可以发现book里面是有值的
【注意】以后编写XXXAction 的时候我们只要实现implements ModelDriver
希望对你们有用!谢谢!!!