MVC 是一个老生常谈的东西早已不是什么稀罕物件,不过在这里还是扒一扒到底都有多少种 MVC。
一、经典 MVC
先说最经典的 MVC,一个请求控制器的请求,负责读取数据,然后将数据派发到试图上。如图:
在经典 MVC 中,可以看到我们请求的页面并不是真正的页面,而是一个控制器。具体显示的页面由这个控制器来决定,大名顶顶的 struts 框架就是这样一种模式。然而,通常为了记忆方便,基于这种经典模式的 MVC 我们通常是把 Controller 的名字起的和 View 一样。
这种模式下,Controller 的职责主要有两个:1、确定显示的最终页面。2、执行页面逻辑准备相关数据。
在 View 中使用的数据是来自 Controller 给予的。
例如“判断当前用户是否登录,如果登录则展现用户详细信息,如果未登录则展现登录界面”。这种场景比较适合这种模式。
二、视图前置 MVC
这是 MVC 的一个变版,在这种模式中 View 的地位被提升到 Controller 之前。也就是说请求是先得到了要显示的页面,而页面中的数据的获取逻辑被后置的 Controller 提供。
这种模式下,Controller 的职责变得只有一个,那就是:执行页面逻辑准备相关数据。视图前置这种模式在职责上更加清晰,但是它失去了对页面展现的控制。
通常在某个数据集中展现的地方会有这种模式的身影,例如:List 页面,在List 页面通常伴随着查询、分页。这种页面中页面本身一般是不会有太大的变化,更多的是后台的数据提取逻辑。
其实这种 MVC 我们也并不陌生,jsp + bean 就是这样一种形式。
三、视图前置 MVC 变版
这是 视图前置 MVC 的一个变版,它的工作模式没有太大的变化。不同的是 View 被进一步前置到 浏览器中,通过 javascript 通过 ajax 的方式访问 Controller。
这种模式下,一般有两类工程师共同开发一个应用程序,他们是:前段工程师、后段工程师。
这种模式的优点在于,前后端开发工程师,只需要协议数据交换格式。即可开始各自的开发工作。也是最常见的一种模式。这也是前后端分离的一种体现。
四、使用 Hasor 实现三种 MVC 模式的开发
-Controller
我们先以 Controller 为例子进行说明,下面是使用 Hasor 开发的 Controller。
@MappingTo("/index.htm")
public class Index {
public void execute(RenderData data) {
data.put("data", new UserData());
}
}
在例子中,我们简单的把 UserData 这个数据写入到 RenderData 对象中。最后在页面渲染的时候再把这个对象拿出来。
当然您也可以像这样,直接把对象塞到 Request 中。
data.getHttpRequest().setAttribute("data", new UserData());
或者干脆更直接一点
@MappingTo("/index.htm")
public class Index {
public void execute(HttpServletRequest request) {
request.setAttribute("data", new UserData());
}
}
除了前面三种方式之外,Haosr 还学习优秀的 JFinal 框架。您可以继承一个类,通过继承类的各种工具方法来实现数据的设置,例如:
@MappingTo("/index.htm")
public class Index extends WebController {
public void execute() {
this.putData("data", new UserData());
// or
this.setAttr("data", new UserData());
}
}
具体想用哪种方式,你喜欢就好。
-实践:经典MVC设计模式
我们可以通过这种方式实现 经典MVC模式。如下:
@MappingTo("/index.htm")
public class Index extends WebController {
public void execute() throws ServletException, IOException {
// 方式 1
this.setAttr("data", new UserData());
getRequest().getRequestDispatcher("/userinfo.htm").forward(getRequest(),getResponse());
// 方式 2
this.setAttr("data", new UserData());
getResponse().sendRedirect("/userinfo.htm");
// 方式 3
this.setAttr("data", new UserData());
renderTo("/userInfo.htm");
}
}
你也可以这样:
@MappingTo("/index.htm")
public class Index {
public void execute(RenderData data) {
data.put("data", new UserData());
data.viewName("/userInfo.htm");
}
}
-实践:视图前置 MVC
前面提到过,前置 mvc 就是一种 jsp + bean 的模式。那么索性就 “JSP + Bean”把。先看负责获取数据的 ManagerBean,为了减少每次获取 UserInfo 时重复创建 Manager 的问题。下面还特意添加了@Singleton注解实现了单例。
@Singleton
public class UserManager {
public UserInfo getUserById(long userId) {
return new UserInfo();
}
}
接下来真的 JSP 登场,为了JSP可以访问到我们的 Bean,你需要引入 Hasor 的 JSP 标签库。接下来通过 hs 库访问我们的 ManagerBean 获取 UserInfo。
<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix="hs" uri="http://project.hasor.net/hasor/schema/jstl" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="zh-CN">
<body>
<hs:findType var="userManager" type="net.demo.hasor.manager.UserManager"/>
<c:set var="userInfo" scope="request" value="${userManager.getUserById(1234)}"/>
姓名:${userInfo.name}<br/>
年龄:${userInfo.age}<br/>
</body>
</html>
下面这个是运行结果:
-实践:视图前置 MVC 变版
在这种模式下我们需要借助一个 Controller 帮我们把数据透给前端 js 程序。浏览器通过请求我们的接口 Controller 来获取数据。接口 Controller 负责返回 json 数据。
@MappingTo("/getUserInfo.json")
public class GetUserInfo {
public UserInfo execute(RenderData data) {
return new UserInfo();
}
}
访问URL运行结果:
其实这种模式,本质上还是经典MVC模式。
来源:oschina
链接:https://my.oschina.net/u/1166271/blog/753001