SpringMVC从入门到放弃之第一章Web MVC简介

说明:本笔记仅是书上的笔记。实验室某个项目学习使用。
单身狗的世界,程序猿的世界,这又是狗又是猿的,我。。。

记笔记记笔记

原文地址

1.1 Web开发中的请求——响应模型:

请求——响应流程图

在Web中,具体步骤如下:
1、Web浏览器(如IE)发送请求,如访问http://sishuk.com
2、Web服务器(如Tomcat)接收请求,处理请求(比如用户新增,则把用户保存一下),最后产生响应(一般为html)。
3、Web服务器处理完成后,返回内容给web客户端(一般就是我们的浏览器),客户端对接收的内容进行处理(如web浏览器会将接收的html内容进行渲染展示给用户)。
所以,在web中都是Web客户端发起请求,Web服务器接收、处理并产生响应。一般的web服务器不能主动通知Web客户端更新内容。但是HTML5 websocket可以实现服务器主动通知Web客户端。

1.2 标准MVC模型概述

MVC模型:是一种架构型的模式,本身不能引入新功能,只是帮助我们将开发的结构组织的更加合理,使展示与模型分离、流程控制逻辑、业务逻辑调用与展示逻辑分离。


MVC模型

首先让我们了解下MVC(Model—View—Controller)三元组的概念:
Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过一般现在都分离开来:Value Object(数据)和服务层(行为)。也就是模型提供了模型数据查询和模型数据状态更新等功能,包含数据和业务。
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想要看到的东西。
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的数据模型返回给视图,由视图负责进行展示。也就是说控制器做了一个调度员的工作。
在标准的MVC模型中能主动推送视图进行更新(观察者设计模式,在模型上注册视图,当模型更新时自动更新视图),但在Web开发中模型是无法主动退给视图(无法主动更新用户界面),因为在Web开发是请求—响应模式。

1.3 Web MVC概述

模型—视图—控制器概念和标准MVC模型一样,接下来我们看看Web MVC模型架构,如下图。


Web MVC模型图

在Web MVC模式下,模型无法主动推送数据给视图,如果用户想要视图更新,需要再发送一次请求(即请求—响应模式)。

1.4Web端开发发展历程

核心历程:


Web开发发展历程

1.4.1 CGI

CGI:(Common Gateway Interface)公共网关接口,一种在Web服务器端使用的脚本技术,使C或Perl语言编写,用于接收Web用户请求并处理,最后动态产生响应给用户,但每次请求将产生一个进程,重量级。

1.4.2 Servlet

Servlet:一种JavaEE web组件技术,是一种在服务器端执行的组件,用户接收web用户请求并处理,最后动态产生响应给用户。但每次请求只产生一个线程(而且有线程池),轻量级。而且能利用很多的JavaEE技术(如JDBC等)。本质就是在java代码里面输出html流。但表现逻辑、控制逻辑、业务逻辑调用混杂,如以下代码。

public class LoginServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);//为了简单,直接委托给dopost处理
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
         * 1.逻辑控制:根据请求参数选择要执行的功能方法
         */
        String submitFlag = request.getParameter("submitFlag");
        if("toLogin".equals(submitFlag)) {
            toLogin(request,response);
            return ;
        } else if("login".equals(submitFlag)) {
            login(request,response);
            return ;
        }
        toLogin(request, response);//默认到登录页面
    }
    
    private void toLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html");
        String loginPath = request.getContextPath() + "/ServletLogin";
        PrintWriter out = response.getWriter();
        /*
         * 2.表现代码:页面展示直接放在我们的Servlet里面
         */
        out.write("<from action='"+loginPath+"' method='post'>");
        out.write("<input type='text' name='submitlogin' value='login'/>");
        out.write("username:<input type='text' name='username'/>");
        out.write("password:<input type='password' name='password'/>"); 
        out.write("<input type='submit' value='login'/>");
        out.write("</from>");
    }
    
    private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1、收集参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //2、验证并封装参数(重复的步骤)
        /*
         * 3.调用业务对象(javabean)进行登录,即模型,不仅包含数据,还包含处理行为
         */
        UserBean user = new UserBean();
        user.setUsername(username);
        user.setPassword(password);
        if(user.login()) {
            response.getWriter().write("login success");
        } else {
            response.getWriter().write("login fail");
        }
    }
}

这种方法是绝对不可取的,控制逻辑、表现代码、业务逻辑对象调用混杂在一起,最大的问题值直接在Java代码中输出Html,这样前端开发人员无法进行页面风格的修改和设计,即使修改也很麻烦,因此实际项目中这种做法不可取。

1.4.3 JSP

JSP(Java Server Page):一种在服务器端执行的web组件,是一种运行在标准的HTML页面中嵌入脚本语言(现在只支持Java)的模板页面技术。本质就是在html代码中嵌入Java代码。最终还是会被编译为Servlet,只不过纯Servlet开发页面简单、方便。但是表现逻辑、业务逻辑、控制逻辑调用还是很混杂。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="com.demo.UserBean"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>登录</title>
</head>
<body>
    <%
        String submintFlag = request.getParameter("submitFlag");
        if ("login".equals(submintFlag)) {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            UserBean user = new UserBean();
            user.setUsername(username);
            user.setPassword(password);
            if (user.login()) {
                out.write("login success");
            } else {
                out.write("login fail");
            }
        } else {
    %>
        <form action="" method="post">
            <input type="hidden" name="submitFlag" value="login">
            username:<input type="text" name="username"/><br>
            password:<input type="password" name="password"/><br>
            <input type="submit" value="login">
        </form>
    <%
        }
    %>
</body>
</html>

这种做法也是绝对不可取的,控制逻辑、业务逻辑、表现代码对象调用混杂在一起,但比直接在Servlet里面输出html要好一点,前端开发人员可以进行简单的页面风格等的设计与修改(但如果嵌入的Java脚本太多也很难修改),因此这种做法也不可取的。


View—Model

JSP本质上还是Servlet,最终在运行时会生成一个Servlet,但这使得写html简单点,但是仍然是控制逻辑、业务逻辑、页面代码混杂在一起的。

1.4.4 Model1

Model1:可以认为是JSP的增强版,可以认为是jsp+javabean
特点:使用<jsp:userBean>标准动作,自动将参数封装为javabean组件;还是必须使用java脚本执行逻辑代码。
Model1架构:


Model1架构

Model1架构中, JSP负责控制逻辑、表现逻辑、业务对象(javabean)的调用,只是比纯JSP简化了获取请求参数和封装请求参数。同样是不好的,在项目中应该禁用。

1.4.5 Model2

Model2:在JavaEE世界里,它可以认为就是Web MVC模型
Model2架构其实可以认为就是我们所说的Web MVC模型,只是控制器采用的Servlet、模型采用JavaBean、视图采用JSP,如下图。


Model2架构

从Model2架构可以看出,视图和模型分离了,控制逻辑与展示逻辑分离了
缺点:
控制器:
1、控制逻辑可能比较复杂,每个模块基本需要一个控制器,造成控制逻辑可能很复杂。
2、请求参数到模型的封装可能比较麻烦,如果交给框架来做这件事情,就得到了解放。
3、选择下一个视图,严重也来ServletAPI,这样很难或基本不可能更换视图。
4、给视图传输要展示的模型数据,使用ServletAPI,更换视图技术要一个更换,很麻烦。
模型:
1、此处模型使用JavaBean,可能造成JavaBean组件类很庞大,一般现在项目都是采用三层结构,而不采用JavaBean。


JavaBean组件==域模型层+业务逻辑层+持久层

视图:
1、现在被绑定JSP,很难更换视图,比如Velocity、FreeMarker;比如我要支持Excel、PDF视图等。

1.4.6 服务到工作者

服务到工作者:Front Controller + Application Controller + Page Controller + Context。即前段控制器+应用控制器+页面控制器+上下文,也是Web MVC,只是职责更加明确,如下图:


Web MVC

运行流程图

职责:
Front Controller:前端控制器,负责为表现层提供统一访问点,从而避免Model2中出现的重复的控制逻辑;并且可以为多个请求提供公用的逻辑,将选择视图和具体功能处理分离。
Application Controller:应用控制器,前端控制器分离选择具体视图和具体的功能处理之后,需要有人来管理,应用控制器就是用来选择具体视图技术(视图的管理)和具体功能处理(页面控制器/命令对象/动作管理),一种策略设计模式的应用,可以很容易的切换视图/页面控制器,互不产生影响。
Page Controller:页面控制器/动作/处理器:功能处理代码、收集参数、封装参数到模型,转调业务对象处理模型,返回逻辑视图交给前端控制器(和具体视图解耦),由前端控制器委托给应用控制器选择具体的视图来展示,可以是命令设计模式的实现。页面控制器也被称为处理器或动作。
Context:上下文,有了上下文之后,我们可以将相关数据放置在上下文,从而与协议无关(如ServletAPI)的访问/设置模型数据,一般通过ThreadLocal模式实现。
目的:
干净的web表现层:
模型和视图的分离;
控制器中逻辑控制和功能处理分离(收集并封装参数到模型对象、业务对象的调用);
控制器中视图选择与具体视图技术分离。
轻薄的web表现层:
做的事情越少越好,薄薄的,不应该包含无关代码;
只负责收集并组织参数到模型对象,启动业务对象的调用;
控制器只返回逻辑视图名由相应的应用控制器来选择具体使用的视图策略;
尽量少使用框架特定API,保证容易测试。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容

  • 额(⊙o⊙)…继续记笔记。。。看看SpringMVC从入门到放弃之第一章Web MVC简介一个在实验室的时候就是这...
    键盘瞎阅读 2,089评论 2 10
  • 这部分主要是与Java Web和Web Service相关的面试题。 96、阐述Servlet和CGI的区别? 答...
    杂货铺老板阅读 1,400评论 0 10
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 3,805评论 0 11
  • 还是很中二的时光里,想要给自己起一个与众不同的网名,从梦雨到依然微笑,总觉得太过矫情与说教。不符合被人称之哥的身份...
    浆果啦啦阅读 395评论 0 0