分布式系统架构:技术栈详解与快速进阶
上QQ阅读APP看书,第一时间看更新

2.1.1 传统交互模式

传统交互模式主要由JSP做动态网页与服务器端MVC模式进行交互,如图2-1所示。

026-1

图2-1 浏览器和服务器端交互

注意,前后端耦合在一起,静态资源(JS、Img、CSS)等同业务程序在同一个工程中,JSP页面会引入JS、CSS、Img等资源。JSP本身可配置标签,用于动态获取数据展示。两者间的交互方式如下。

1)通过标签。如常用Form表单,通过HTTP传输方式,指定服务器端URL进行传输,服务器端通过处理,返回数据,JSP页面通过标签获取到数据展示。

2)通过引入JS。通过Ajax异步请求方式,页面端Ajax可以和服务器端约定好数据体格式,对页面参数组装后,通过HTTP传输方式,指定服务器端URL进行传输,服务器端通过处理,返回数据,Ajax接收到数据后进行解析并最终展示。

最开始使用第一种方式,页面本身支持,无须引入其他组件。因为页面需要定期展示新的数据而需要刷新,用户体验较差。为了解决页面无刷新动态获取数据,提高用户体验,诞生了第二种方式——Ajax异步请求方式。特点是用户无感知,动态获取服务器端数据,提高用户体验。

服务端采用MVC模式,即Model(模型)、View(视图)、Controller(控制器),这种模式主要体现在模型和视图分离,让一个程序有多种展示形式。

在网页中视图层指用户能够看到并与其交互的界面。MVC可以提供多种视图模型,视图中不展示用户数据,它只是一种输出数据并允许用户操作的方式。模型层指业务规则,可以处理不同业务的任务,模型和数据格式无关,同样一个模型可以为多个视图提供数据。控制器层指接收用户的输入并会调用模型层和视图层去完成业务功能,控制器本身不输出任何数据和格式,控制器主要接收请求并决定它会调用哪个模型去构造并处理请求,以及最后会选择哪个视图来显示数据。

前后端交互工程结构如图2-2所示。

027-1

图2-2 前后端交互工程结构示意图

下面介绍如何用JSP引入静态资源代码,具体如代码清单2-1所示。

代码清单2-1 用JSP引入静态资源代码

<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="${pageContext.request.contextPath}/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.11.0.min.js"></script>
<title>demo</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/demo/query" method="POST">
        标题: <input type="text" id=”title” />
        查询:<input type="submit" id=”query”/>
    </form>

</body>
</html>

通过JS内置传统Ajax异步获取服务器端数据,具体如代码清单2-2所示。

代码清单2-2 JS内置传统Ajax异步获取数据代码

query.onclick = function(){
        var data= document.getElementById("title");
        var request = createXHR();
        request.onreadystatechange = function(){
            if(request.readyState === 4){
                if(request.status === 200){
                    createResult.innerHTML = request.responseText;
                }else{
                    alert("发生错误"+request.status);
                }
            }
        };
        request.open("POST", contextPath+"/demo/query",false);
        request.send(data);
    }

在jQuery中通过Ajax异步获取服务器端数据,如代码清单2-3所示。

代码清单2-3 jQuery封装Ajax异步获取数据代码

$.ajax({
                type:"POST",
                url: contextPath+"/demo/query",
                dataType:"json",
                data:{
                    title:$("#title").val()
                },
                success:function(data){
                    if(data.success){
                        $("#createResult").html(data.msg);
                    }else{
                        $("#createResult").html("出现错误:"+data.msg);
                    }
                },
                error: function(jqXHR){
                    alert("发生错误:"+jqXHR.status);
                }
            });

在服务器端通过MVC模式处理数据,如代码清单2-4所示。

代码清单2-4 服务器端MVC模式代码

public class GoodsServlet extends HttpServlet{

    private static final long serialVersionUID = -5352453280392723315L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("html/text;charse=utf-8");

        /**
         * 获取查询条件
         */
        String title = request.getParameter("title");

        /**
         * 控制器层调用模型层
         * 实例化service
         * 获取数据返回信息
         */
        GoodsInfoService goodsService = new GoodsServiceImpl();
        Goods goods = goodsService.query(title);

        // 存储页面展示数据,控制器层调用视图层
        request.getSession().setAttribute("goods", goods);
        response.sendRedirect("demo.jsp");

    }
}

传统交互模式存在如下问题。

1)静态资源页面和服务器端代码属于同一工程,耦合性较强。

2)部署在同一个服务器,影响面较广。

3)JSP页面获取数据后需要编译,性能较差。

4)页面渲染速度较差,影响用户体验。

5)横向扩展复杂,分摊压力能力差。