您的位置:首页 > 编程语言 > Java开发

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

2017-01-23 14:08 429 查看

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();

}

[/code]
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>

[/code]
更多细节这里不做展开,请参考笔记:XMLHTTPRequest对象和DOM(笔记内跳转 / 共享链接跳转

AJAX校验用户名实例(笔记内跳转 / 共享链接跳转

2、JSON替代XML的优势

在标题1中我们提到的AJAX中X实际上是XML,这里我们要换成JSON,为什么要采取JSON呢?1)数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;2)易于解析,客户端JavaScript可以简单的通过eval_r()进行JSON数据的读取。
另外,JSON是趋势,我们要跟着大势走,顺水推舟,不要没事就去逆流而上。
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>

[/code]
添加org.json.jar,用来解析json

如果你是用的Maven方式,你可以直接添加依赖
<!--JSON-->

<dependency>

<groupId>org.json</groupId>

<artifactId>json</artifactId>

<version>20160810</version>

</dependency>

[/code]

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>

[/code]重点注意的是:这里不再继承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返回对象

  ... ...

}

[/code]
result中使用了root参数(<param name="root">userInfo</param>)后返回的json数据:
{"userInfo":[

  {"userId":"Patrick", "userName":"123456"}

  ]}

[/code]
result中没有设置root参数返回Action中的json数据:
{"data":[

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

  {"message":"testMesssageData"}

  ]}

[/code]

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";

}

}

[/code]这里为了验证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 + ">"

+ "          "

+ message + "</font>";

}

});

});

[/code]
<div id="loginNameMsg"></div>

<div class="login_sr">账号:<s:textfield cssClass="login_inputYhm" name="sysUser.loginName" id="loginName" />

[/code]这里值得一提的就是JQuery的$.post()方法,原型是ajax(),通过 HTTP 请求加载远程数据,返回其创建的 XMLHttpRequest 对象。$.post()是其简单易用的高层实现,详见 jQuery ajax - post() 方法jQuery ajax - ajax() 方法jQuery 参考手册 - Ajax

至此,已经OK。

4、源码和参考链接

关于更多详细的代码变动,可以在我的Github中参考具体源码项目源码地址 deng-cc/KeepLearning

before 采用AJAX+JSON commit id:ff310e744b317465e2ab99e90549cc9983736212
after 采用AJAX+JSON v1 commit id:8f34e130edfe61ddf423b81f00393e18bf26170a
after 采用AJAX+JSON v2(Struts动态方法访问形式) commit id:581407758e021a7e06fb866618ed7b21dd4e9b2d
after 采用AJAX+JSON v3(重构AJAX在struts配置中的信息传递方式) commit id:933d5cdd19909c995be62856d37596c4b4f74c4e

参考链接:JSON中result的root属性

Struts2+Jquery+Ajax+Json

Struts2 url中包含感叹号实现动态方法调用

struts2+ajax+json使用实例

Struts 2三种方式实现Ajax

jQuery ajax - post() 方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: