一.MVC设计模式
概念:
MVC(Model-View-Controller)是一种常用的软件设计模式,用于组织和管理应用程序的代码。它将应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller),各司其职,相互之间有明确的分工。
解释:
模型(Model):模型是应用程序的数据和业务逻辑的核心部分。它负责处理数据的存取、操作和验证,以及执行业务规则。模型通常包括数据对象、数据库交互、文件操作等。它可以从数据库、文件或其他数据源中获取数据,并对数据进行操作和更新。模型不依赖于视图和控制器,可以在不改变其他部分的情况下进行独立的测试和修改。
视图(View):视图是应用程序的用户界面,负责展示数据给用户,并接收用户的输入。视图可以是图形界面、网页、命令行界面等,根据具体的应用场景而定。视图通常从模型中获取数据,并将其呈现给用户。它可以将用户的操作发送给控制器进行处理。
控制器(Controller):控制器是模型和视图之间的桥梁,负责接受用户的输入并做出相应的响应。它从视图接收用户的操作,然后根据具体的业务逻辑调用模型进行数据处理,最后将处理结果返回给视图进行展示。控制器还可以根据需要更新模型或视图。控制器的存在使得模型和视图可以独立于对方进行修改和测试。
好处 :
模块化:MVC将应用程序分为不同的部分,使每个部分都独立于其他部分。这样可以提高代码的可读性、可测试性和可维护性。
分工明确:不同的角色负责不同的任务,使开发人员能够更好地协作,提高开发效率。
可扩展性:由于MVC遵循松耦合的原则,因此可以更容易地添加新的模型、视图和控制器,以满足应用程序的新需求。
可重用性:模型、视图和控制器之间的分离使得它们可以在不同的应用程序中重用,提高代码的复用性。
二.利用XML和反射优化MVC架构
1.步骤
(1).编写ConfigModel模型存放子控制器
(2).利用init方法初始化configModel对象
(3).通过uri获取ConfigModel中的属性(path)
(4)通过path获取到type
(5).再利用它反射获取到forward
package com.YU.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.YU.framework.model.ActionModel;
import com.YU.framework.model.ConfigModel;
import com.YU.framework.model.ConfigModelFactory;
import com.YU.web.BookAction;
import com.YU.web.OrderAction;
/**
* ActionServlet:中央控制器
*
* @author 21879
*
*/
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
// 定义ConfigModel存放子控制器
private ConfigModel configModel;
// 初始化configModel
@Override
public void init() throws ServletException {
try {
// configModel包含了所有的子控制器
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 uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// 通过uri获取到ConfigModel中的path
ActionModel actionmodel = configModel.pop(uri);
// 判断配置XML时是否配置了path
if (actionmodel == null)
throw new RuntimeException("action not config");
String type = actionmodel.getType();
// 获取到type后利用反射获取到它的forward
Action action;
try {
action = (Action) Class.forName(type).newInstance();
action.execute(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
注:在获取XML配置时需要判断是否配置当前属性

三.结果集页面配置
步骤:
1.修改子控制器的方法的返回值,将结果对象返回
package com.YU.framework;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 子控制器,向浏览器发送请求
* @author 21879
*
*/
public class Action {
public String execute(HttpServletRequest req,HttpServletResponse resp) {
//获取请求参数
String methodName = req.getParameter("methodName");
String res = "";
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;
}
}
2.将继承子控制器的方法的返回值修改成和子控制器一样的类型

3.获取业务代码返回值
//具体业务代码的返回值
String res = action.execute(req, resp);
4.通过返回值判断是重定向还是转发
//通过返回值判断结果是重定向还是转发
ForwardModel forwardModel = actionmodel.pop(res);
if(forwardModel!=null) {
boolean redirect = forwardModel.isRedirect();
//获取要跳转的页面
String path = forwardModel.getPath();
if(redirect) {
resp.sendRedirect(req.getContextPath()+ path);
}else {
req.getRequestDispatcher(path).forward(req, resp);
}
}
} catch (Exception e) {
e.printStackTrace();
}
注意点:
1.增删改是重定向,转发会导致表单重复提交,导致数据重复操作紊乱
查询使用转发,刷新数据快,效率高
2.在重定向跳转页面的时候会导致路径错误,项目丢失
解决措施:在要跳转的Path前面加上req.getContextPath()
完整代码
package com.YU.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.YU.framework.model.ActionModel;
import com.YU.framework.model.ConfigModel;
import com.YU.framework.model.ConfigModelFactory;
import com.YU.framework.model.ForwardModel;
import com.YU.web.BookAction;
import com.YU.web.OrderAction;
/**
* ActionServlet:中央控制器
*
* @author 21879
*
*/
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
// 定义ConfigModel存放子控制器
private ConfigModel configModel;
// 初始化configModel
@Override
public void init() throws ServletException {
try {
// configModel包含了所有的子控制器
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 uri = req.getRequestURI();
uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
// 通过uri获取到ConfigModel中的path
ActionModel actionmodel = configModel.pop(uri);
// 判断配置XML时是否配置了path
if (actionmodel == null)
throw new RuntimeException("action not config");
String type = actionmodel.getType();
// 获取到type后利用反射获取到它的forward
Action action;
try {
action = (Action) Class.forName(type).newInstance();
//具体业务代码的返回值
String res = action.execute(req, resp);
//通过返回值判断结果是重定向还是转发
ForwardModel forwardModel = actionmodel.pop(res);
if(forwardModel!=null) {
boolean redirect = forwardModel.isRedirect();
//获取要跳转的页面
String path = forwardModel.getPath();
if(redirect) {
resp.sendRedirect(req.getContextPath()+ path);
}else {
req.getRequestDispatcher(path).forward(req, resp);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
四.优化参数封装
1.获取表中类属性对象
(1)创建模型驱动接口
package com.YU.framework;
/**
* 模型驱动接口
* @author 21879
*
* @param <T>
*/
public interface ModelDriver<T> {
T getModel();
}
2.获取到所有参数及参数req,getParamenterMap()
action = (Action) Class.forName(type).newInstance();
//判断bookAction有没有实现ModelDriver接口
if(action instanceof ModelDriver) {
ModelDriver md = (ModelDriver) action;
Object bean = md.getModel();
}
3.将参数值封装到表对应的对象中
//利用Spring工具类将值和键存放到map集合中
BeanUtils.populate(bean, req.getParameterMap());
注意点:
1.利用map集合将属性和值存储到模型对象中
2.要判断模型对象是否存在
五.什么是框架
一、什么是框架?
框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。
IT语境中的框架,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构。在此结构上可以根据具体问题扩展、安插更多的组成部分,从而更迅速和方便地构建完整的解决问题的方案。
1)框架本身一般不完整到可以解决特定问题,但是可以帮助您快速解决特定问题;没有框架所有的工作都从零开始做,有了框架,为我们提供了一定的功能,我们就可以在框 架的基础上开发,极大的解放了生产力。不同的框架,是为了解决不同领域的问题。一定要为了解决问题才去学习框架。
2)框架天生就是为扩展而设计的;
3)框架里面可以为后续扩展的组件提供很多辅助性、支撑性的方便易用的实用工具(utilities),也就是说框架时常配套了一些帮助解决某类问题的库(libraries)或工具(tools)。java中就是一系列的jar包,其本质就是对jdk功能的扩展。