Struts+Spring+Hibernate項目整合AJAX+JSON


1、什么是AJAX

AJAX是 “Asynchronous JavaScript and XML” 的簡稱,即異步的JavaScript和XML。

所謂異步,就是提交一個請求不必等待響應回來,可以直接去做其他事情。同步則是提交請求必須等待結果返回才能進行下一步操作。 同時,異步能夠局部刷新頁面,比如網站常見的輸入用戶名后的局部顯示該用戶名是否可用的信息,這種可以更好地提高用戶體驗。

接下來我們回顧一下AJAX的基本用法:
核心對象 XMLHttpRequest,它是瀏覽器內部的對象,可以用來發送HTTP請求和接收HTTP響應。它的實現根據瀏覽器可能有不同,一般創建需要進行條件判斷
if(window.ActiveObject) { 
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest();
}

XMLHttpRequest的重要屬性
  • readyState  ——  返回當前請求狀態,用0-5表示
  • status  ——  返回當前服務器的狀態,用數字(狀態碼)表示,如200、500、404 etc.
  • statusText ——  功能同status,不同點在於它以文本的形式進行表示
  • onreadystatechange  ——  事件觸發器,readyState/status發生變化會觸發該項
  • responseText  ——  接收服務器端返回的文本內容,以字符串形式存在
  • responseXML  ——  接收服務器響應,以XML存在,可以解析為一個DOM對象

XMLHttpRequest的重要方法
  • open() --> e.g. open("GET", url, true)
  • send() --> e.g. send(null)

下面是一個簡單例子

<script type="text/javascript"> 
var xmlHttp;

//創建XMLHttpRequest對象
function createXMLHttpRequest() {
    if(window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHttp");
    } else if(window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}

function validate() {
    //todo 編寫Ajax校驗,發送請求和處理,並且顯示信息
    //創建createXMLRequest對象
    createXMLHttpRequest();
    //使用DOM,得到id值是username的域
    var username = document.getElementById("username");
    var url = "ValidateUsernameCtl?username=" + escape(username.value);
    //向服務器端的ValidateUsernameCtl發送異步請求
    xmlHttp.open("GET", url, true);
    xmlHttp.onreadystatechange = callback;
    xmlHttp.send(null);
}

function callback() {
    if(xmlHttp.readyState == 4) {
        if(xmlHttp.status == 200) {
            //以responseXML屬性,接收服務器端返回的xml文件,使用DOM進行解析
            var msg = xmlHttp.responseXML.getElementsByTagName("message")[0].firstChild.data;
            var passed = xmlHttp.responseXML.getElementsByTagName("passed")[0].firstChild.data;
            setMessage(msg, passed);
        }
    }
}

function setMessage(message, passed) {
    var validateMessage = document.getElementById("usernamemsg");
    var fontColor = "red";
    if(passed == "true") {
        fontColor = "green";
    }
    //對<div name="usernmaesg">的地方設置其間的代碼innerHTML為指定代碼
    validateMessage.innerHTML = "<font color=" + fontColor + ">" + message + "</font>";
}
</script>



2、JSON替代XML的優勢

在標題1中我們提到的AJAX中X實際上是XML,這里我們要換成JSON,為什么要采取JSON呢?
1)數據格式比較簡單,易於讀寫,格式都是壓縮的,占用帶寬小;
2)易於解析,客戶端JavaScript可以簡單的通過eval_r()進行JSON數據的讀取。

另外,JSON是趨勢,我們要跟着大勢走,順水推舟,不要沒事就去逆流而上。



3、SSH整合AJAX(JSON)的步驟

網上類似的博客幾乎都是相同的在不停轉載,這個跟我參考的那位網友的感覺是一樣,參考的帖子很少,於是自己也鼓搗了很久才解決。Struts2實際上有多種方式實現AJAX,可以參考博文《 Struts 2三種方式實現Ajax》,這里為了更好地結合JSON,采用了struts2-json插件的方式。

3.1 配置准備

3.1.1 添加jar包

  • 添加struts2-json-plugin-x.x.x.x.jar,用來支持struts和ajax-json的集成
如果你是用的Maven方式,你可以直接添加依賴
<!--struts + ajax json //tips struts 整合 ajax json--> 
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-json-plugin</artifactId>
            <version>2.3.16.1</version>
        </dependency>

  • 添加org.json.jar,用來解析json
如果你是用的Maven方式,你可以直接添加依賴
<!--JSON--> 
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160810</version>
        </dependency>

3.1.2 配置struts.xml

<package name="ajax" namespace="/ajax" extends="json-default" > 
        <action name="ajaxAction" class="ajaxAction">
            <!-- 返回類型為json-->
            <result name="register" type="json">
                <!--tips 參數root的含義-->
                <param name="root">message</param>
            </result>
        </action>
</package>
重點注意的是
  • 這里不再繼承struts-default,而是json-default(這個文件在我們引入的struts-json插件包中就有配置)
  • type需要修改為json
  • <param name="root">message</param> 這里我們單獨來敘述

這里最難理解的大概就是這個<param name="root">message</param>了,下面來簡單說說到底是什么意思(參考鏈接: JSON中result的root屬性):
所謂root的含義,是指返回的json數據為指定的對象(Action中作為屬性的那個類),例如我的源碼中AjaxAction中為Message message,將返回和Message對等的json對象如果沒有指定root屬性,則默認使用Action作為返回的json對象。

是否使用Action作為返回的json數據的根,區別如下: 
例如有Action如下,含兩個屬性 String message、 UserInfo userInfo

public class JsonJqueryStruts2Action extends ActionSupport {  
  private String message; //使用json返回單個值 
  private UserInfo userInfo; //使用json返回對象 
  ... ... 
}

result中使用了root參數(<param name="root">userInfo</param>)后返回的json數據: 

{"userInfo":[ 
  {"userId":"Patrick", "userName":"123456"}  
  ]} 

result中沒有設置root參數返回Action中的json數據: 

{"data":[ 
  {"userInfo":[ {"userId":"Patrick", "userName":"123456"} ] },  
  {"message":"testMesssageData"} 
  ]} 


3.2 編寫Action

package com.zker.action;
 
import com.opensymphony.xwork2.ActionSupport;
import com.zker.common.util.Message;
import com.zker.common.util.SpringContextUtils;
import com.zker.dao.user.UserDao;
import org.json.JSONObject;

import java.io.IOException;


public class AjaxAction extends ActionSupport {
    /**用來接受封裝的參數 LoginName 用戶名*/
    String loginName;

    /**封裝信息,為了測試JSON刻意做成簡單的類*/
    Message message = new Message();

    /**用來返回用於js接收*/
    String result;

    //tips 要有getter&setter,否則$post的param參數傳遞不過來
    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    /**
     * 利用Ajax實現注冊的用戶名重復性校驗
     * @return
     */
    public String ajaxRegister() throws IOException {
        //tips 如何手動取出容器中的bean?答案如下
        UserDao userDao = (UserDao)SpringContextUtils.context.getBean("userDao");
        if (userDao.findAdminByLoginName(loginName) != null
                || userDao.findUserByLoginName(loginName) != null) {
            message.setMsg("用戶名已存在");
            message.setStatus(false);
        } else {
            message.setMsg("用戶名可以注冊");
            message.setStatus(true);
        }

        /*
        //JSON-String轉換 obj -> jsonStr
        //當struts-login.xml中root為result時,此處才需要解開
        this.result = JSONObject.wrap(message).toString();
        */

        return "register";
    }
}
這里為了驗證AJAX+JSON,故意采取的建立一個Message類來傳遞信息,多此一舉只為學習,實際操作請注意。其他信息詳見代碼,這里不做具體展開。

3.3 編寫JS

<!--Ajax + JSON-->
    $(document).ready( function() { 
        //使用 Ajax 的方式 判斷登錄
        $("#loginName").blur( function() {
            var url = "/ajax/ajaxAction!ajaxRegister";
            var params = {loginName : $("#loginName").val()};

            /*method1 <param name="root">result</param>
            $.post(
                    url,  //服務器要接受的url
                    params,  //傳遞的參數
                    function validateLoginName(result){ //服務器返回后執行的函數 參數msg保存的是服務器發送到客戶端的數據
                        //alert("服務器端返回的data --> " + result);
                        var msgObj = eval("(" + result + ")"); //jsonStr -> jsObj(jsonObj)
                        var passed = msgObj.status;
                        setMessage(msgObj.msg, passed);
                    },
                    'json' //數據傳遞的類型  json
            );
            */

            /*method2 <param name="root">message</param> */
            $.post(
                    url,  //服務器要接受的url
                    params,  //傳遞的參數
                    function validateLoginName(message){ //服務器返回后執行的函數 參數是服務器發送到客戶端的數據
                        var msg = message.msg;
                        var passed = message.status;
                        setMessage(msg, passed);
                    },
                    'json' //數據傳遞的類型  json
            );

            function setMessage(message, passed) {
                var validateMessage = document.getElementById("loginNameMsg");
                var fontColor = "red";
                if(passed) {
                    fontColor = "green";
                }
                //對<div name="loginNameMsg">的地方設置其間的代碼innerHTML為指定代碼
                validateMessage.innerHTML = "<font color=" + fontColor + ">"
                        + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
                        + message + "</font>";
            }
        });
    }); 
<div id="loginNameMsg"></div> 
<div class="login_sr">賬號:<s:textfield cssClass="login_inputYhm" name="sysUser.loginName" id="loginName" />
這里值得一提的就是JQuery的$.post()方法,原型是ajax(),通過 HTTP 請求加載遠程數據,返回其創建的 XMLHttpRequest 對象。
$.post()是其簡單易用的高層實現,詳見  jQuery ajax - post() 方法jQuery ajax - ajax() 方法jQuery 參考手冊 - Ajax

至此,已經OK。 



4、參考鏈接



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM