從MVC到Ajax再到先後端分離的思考

  前言

  一位小妹去面試前端,前端leader問了"什麼是ajax?",答:「接收後臺的數據,而後而後本身填充和渲染樣式」;一位小哥去面試後臺,技術經理問了「什麼是ajax?」,答:「在不需從新加載整個網頁的狀況下,發送異步請求,返回json數據給前端」。準確答案究竟是什麼?Ajax到底屬於前端仍是屬於後端?前端(或者後端)到底需不須要懂得Ajax?Ajax請求與普通的http請求有什麼區別?數據庫中的數據經過Ajax請求和普通請求下分別是怎麼傳遞到前臺的...等等一些問題,彷佛須要靜下心來理一理。javascript

  MVC篇

  最典型的MVC就是JSP + servlet + javabean的模式,很多人的web起點應該也是這個,記得當時看到最多的問題就是JSP和Servlet區別,後來隨着Struts 、Spring MVC等框架出來,MVC被談論的更多了,愈來愈多的人開始想要深刻學習和理解它,同時也有愈來愈多的問題開始圍繞MVC展開。基本的概念:MVC = Model View Controller = 模型-視圖-控制器,太過於概念化的東西確實不太好理解,也許框架都用了好幾年,一問MVC仍是會懵。不過仍是Talk is cheap,下面以Spring MVC + jsp的開發過程示例,同時也是數據在普通http請求後從數據庫傳遞到前端的過程。html

  背景:ssm項目中,將數據庫中TBL_PERSON表的記錄所有獲取,在前端以表格呈現出來,即<table>標籤下(由於本身寫的樣式實在太醜,重點關注過程吧)前端

  1.Controller層關鍵代碼

package com.mmm.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mmm.pojo.Person;
import com.mmm.service.PersonService;

@Controller
@RequestMapping("person")
public class PersonController {
    
    @Autowired
    PersonService personService;
    
        /**
     * 框架跳轉頁面默認是forward,也就是請求轉發
     * 這裏的model設置的屬性,在jsp頁面也能直接經過el表達式獲取
     * */
    @RequestMapping(value="httplist")
    public String httplist(Model model) {
        List<Person> list = personService.selectAll();
        model.addAttribute("list", list);
        return "person/list";
    } 
    
    ......
}

  2.jsp頁面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
    <title>Person列表</title>   
  </head>
  
  <body>
    <table>
        <tr>
            <th>姓名</th>
            <th>性別</th>
        </tr>
        <c:forEach var="i" begin="0" end="${list.size() }">
            <tr>
                <td>${list[i].name }</td>
                <td>${list[i].gender }</td>
            </tr>
        </c:forEach>
    </table>
  </body>
</html>

  3.tomcat啓動項目,地址欄輸入http://localhost:8081/mm-web/person/httplist,便可看到以下頁面,獲取到了數據庫中完整數據

  Ajax篇

  傳統web開發在沒有應用Ajax技術的時候,每每頁面是用jsp,而這也讓咱們看到MVC的不足,視圖與控制器間的過於緊密的鏈接,每次請求必須通過「控制器->模型->視圖」這個流程,當java腳本 + 各類表達式 + html代碼 +javascript代碼混雜一塊的時候,簡直痛不欲生,代碼可讀性十分差,並且給後面維護和修改代碼的人帶來很大阻礙。再說下Ajax,首先簡單介紹下,Ajax = 異步 Javascript 和 XML,聽名字不難發現,並未涉及到後端java代碼,核心對象XMLHTTPRequest(可擴展超文本傳輸請求),經過它,咱們能夠在不刷新頁面的狀況下,發送異步請求至後臺,並獲取後臺返回的json數據。說的簡單點,就是不刷新或者跳轉頁面,發送請求而後拿數據,在這裏,比較重要的一點,主動權是在前臺這邊,前臺拿到數據後再根據需求去填充數據內容,渲染樣式,實現頁面效果。並且因爲Ajax基於的Javascript屬於前端腳本,並不依賴於jsp環境,頁面寫Html也是能夠的。因此下面以Spring MVC + Ajax + jsp示例(這裏的ajax採用Jquery寫法,工做中通常也是應用Jquery較多,原生js寫法相較繁瑣一點,這裏就不展現了),同時爲了區別返回json數據和直接跳轉頁面的區別,在控制器中寫了兩個方法,一個用於跳轉頁面,但並未拿到數據,等頁面載入後,經過js發起Ajax請求到控制層拿到數據,再動態填充到頁面,而且無需刷新頁面,因此後面咱們在地址欄輸入地址後,看上去像一次請求,其實一共兩次。java

  1.Controller層關鍵代碼

package com.mmm.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mmm.pojo.Person;
import com.mmm.service.PersonService;

@Controller
@RequestMapping("person")
public class PersonController {
    
    @Autowired
    PersonService personService;
    
    /**
     * 這裏接受地址欄請求,僅起到轉發頁面做用,並未傳遞到咱們數據庫的內容
     * */
    @RequestMapping(value="toPage")
    public String httplist() {
        return "person/list";
    } 
    
    /**
     * 這裏@ResponseBody表明該方法接受請求後不是跳轉頁面,而是直接返回json數據
     * 注意引入json相關jar包,還有spring MVC配置中不要漏掉<mvc:annotation-driven/>
     * */
    @RequestMapping(value="ajaxlist")
    @ResponseBody
    public List<Person> ajaxlist() {
        List<Person> list = personService.selectAll();
        return list;
    } 
    
    ......
}

   2.jsp頁面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
    <title>Person列表</title>
    <!-- 引入Jquery -->
    <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script> 
    <!-- 編寫腳本 -->
    <script type="text/javascript">
        $(function() {
            $.ajax({
                url: '${pageContext.request.contextPath}/person/ajaxlist',
                type: 'post',
                dataType: 'json',
                success: function(data) {//這裏的data表明的就是返回person集合list
                    var html = "";
                    html += "<tr><th>姓名</th><th>性別</th></tr>";
                    for(var i in data){
                        html += "<tr><td>"+data[i].name+"</td><td>"+data[i].gender+"</td></tr>";
                    }
                    $("table").html(html);
                }
            });
        });
    </script>
  </head>
  
  <body>
    <table>
    </table>
  </body>
</html>

  3.tomcat啓動項目,地址欄輸入http://localhost:8081/mm-web/person/toPage,便可看到以下頁面,一樣獲取到了數據庫中完整數據(是兩次請求)

 

  關於先後端分離

  在傳統的java web項目中,應用MVC框架,Jsp想作的事太多,既有後臺數據的處理手法,也要承擔視圖展示的職能,Java代碼、Html、CSS、Javascript、各類表達式、發送請求、接收數據、頁面跳轉...甚至有點全能的感受,但正是這種全能,讓本該分工明確個的各單位糅雜在一塊兒,給開發也帶來了一些麻煩。使用Ajax,才真正有點分離的感受,至少咱們知道html、CSS、Js是屬於前端版塊,後臺專一於業務邏輯和數據處理,讓前臺拿到結果,而後填充內容或者進行局部動態更新,渲染一下頁面效果,先後端真正的交互在於這個json數據的請求和返回,而json的本質是 JS 對象的字符串表示法,是字符串,數據格式,以鍵值對呈現[以下圖所示]。後臺有一個對象轉化爲json的過程,反過來,json傳遞到前端後,應該有一個內容解析/解讀的過程,要知道哪一個鍵對應的值是表明什麼含義,該怎麼處理。最後,關於AJax到底屬於前端仍是後端,我的理解是,使用的前端技術,但主要目的是做用於先後端數據交互(請求--獲取--處理的過程),而後到底先後端誰該懂得Ajax的問題,以爲只要想一想本身做爲前端/後端徹底不懂這個的話會不會對本身造成障礙,就有本身的答案了。jquery

  小結

  應用傳統的web開發模式,成熟的框架逐步在完善,不過絕大部分框架都是針對前端或者後端,前端層出不窮的樣式插件模板,後臺不斷更新的數據操做和技術選型,可是針對先後端交互的部分,我的以爲還有很大的提高空間。以Jsp爲例,熟悉前端的(全棧?)後臺開發人員操做起來會相較方便,雖然他的雜合先後端代碼廣受詬病,可是事實是,Jsp仍然有許多項目是採用的Jsp開發。html + Ajax + js有許多優秀的性質,也還有不少須要完善的地方。目前Ajax應用的已經比較普遍了,因此項目中每每會有兩種請求混雜的狀況(比較直觀就是咱們應用Spring MVC時,控制層裏的方法,有的加了@Responsebody註解,有的則沒有),能夠根據項目的須要決定是否採用。web

相關文章
相關標籤/搜索