Ajax简述
Ajax(Asynchronous JavaScript And XML),即异步JavaScript和XML技术,是指一种创建交互式网页应用的网页开发技术,这个术语源自描述从基于 Web 的应用到基于数据的应用的转换。在基于数据的应用中,用户需求的数据如联系人列表,可以从独立于实际网页的服务端取得并且可以被动态地写入网页中,改善了缓慢的Web应用体验,使之像桌面应用一样。
目前,编写应用程序时有两种基本的选择:
1· 桌面应用程序
2· Web 应用程序
桌面应用程序通常要求安装到计算机上,桌面应用程序可能使用互联网下载更新,但运行这些应用程序的代码在桌面计算机上。Web 应用程序运行在某处的 Web 服务器上,要通过 Web 浏览器访问这种应用程序。
更重要的问题是,应用程序如何运转以及如何与其进行交互。桌面应用程序一般很快(就在本地计算机上运行,不用等待互联网连接),具有漂亮的用户界面(通常和操作系统有关)和非凡的动态性。可以单击、选择、输入、打开菜单和子菜单、到处巡游,基本上不需要等待。
另一方面,Web 应用程序是最新的潮流,它们提供了在桌面上不能实现的服务(比如 Amazon.com 和 eBay)。但是,伴随着 Web 的强大而出现的是等待,等待服务器响应,等待屏幕刷新,等待请求返回和生成新的页面。
Ajax 尝试建立桌面应用程序的功能和交互性与不断更新的 Web 应用程序之间的桥梁。试图在 Web 应用程序中可以使用像桌面应用程序中常见的动态用户界面和漂亮的控件。
Ajax 的核心是 JavaScript 对象 XMLHttpRequest。该对象在 Internet Explorer 5 中首次引入,它是一种支持异步请求的技术。
XMLHttpRequest是一个 JavaScript 对象,创建该对象很简单。
//创建新的 XMLHttpRequest 对象
<script language="javascript" type="text/javascript">
var xmlHttp = new XMLHttpRequest();
</script>
在一般的 Web 应用程序中,用户填写表单字段并单击 Submit 按钮。然后整个表单发送到服务器,服务器将它转发给处理表单的脚本(通常是 PHP 或 Java,也可能是 CGI 进程或者类似的东西),脚本执行完成后再发送回全新的页面。该页面可能是带有已经填充某些数据的新表单的 HTML,也可能是确认页面,或者是具有根据原来表单中输入数据选择的某些选项的页面。当然,在服务器上的脚本或程序处理和返回新表单时用户必须等待。屏幕变成一片空白,等到服务器返回数据后再重新绘制。这就是交互性差的原因,用户得不到立即反馈,因此感觉不同于桌面应用程序。
Ajax 基本上就是把 JavaScript 技术和 XMLHttpRequest 对象放在 Web 表单和服务器之间。当用户填写表单时,数据发送给一些 JavaScript 代码而不是 直接发送给服务器。相反,JavaScript 代码捕获表单数据并向服务器发送请求。同时用户屏幕上的表单也不会闪烁、消失或延迟。换句话说,JavaScript 代码在幕后发送请求,用户甚至不知道请求的发出。更好的是,请求是异步发送的,就是说 JavaScript 代码(和用户)不用等待服务器的响应。因此用户可以继续输入数据、滚动屏幕和使用应用程序。
然后,服务器将数据返回 JavaScript 代码(仍然在 Web 表单中),后者决定如何处理这些数据。它可以迅速更新表单数据,让人感觉应用程序是立即完成的,表单没有提交或刷新而用户得到了新数据。JavaScript 代码甚至可以对收到的数据执行某种计算,再发送另一个请求,完全不需要用户干预!这就是 XMLHttpRequest 的强大之处。它可以根据需要自行与服务器进行交互,用户甚至可以完全不知道幕后发生的一切。结果就是类似于桌面应用程序的动态、快速响应、高交互性的体验,但是背后又拥有互联网的全部强大力量。
简而言之,XMLHttpRequest使您可以使用 JavaScript 向服务器提出请求并处理响应,而不阻塞用户。
这方面的应用实例很多,如Google Suggest 使用 AJAX 创造出动态性极强的 web 界面:在谷歌的搜索框输入关键字时,JavaScript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。
struts2的Ajax支持
struts2.0曾经对DWR和Dojo进行了封装,试图提供强大的Ajax支持,但从struts2.1开始,struts2的核心功能不再提供基于Dojo的Ajax支持,而是把Ajax支持放入Dojo插件内。
struts2支持一种Stream类型的Result,这种类型的Result可以直接向客户端浏览器生成二进制响应、文本响应等。这样就可以让struts2的Action直接生成文本响应,然后在客户端页面动态加载该响应。
下面将一个简单的Ajax登录示例,浏览者输入用户名、密码后,用户能以异步方式提交请求,而struts2的Action则直接输出登录结果,无需使用额外的JSP页面。先看Action类代码。
package com.afy.app.action;
import com.opensymphony.xwork2.Action;
import java.io.*;
public class LoginAction implements Action{
// 封装请求参数的两个成员变量
private String user;
private String pass;
// 封装输出结果的二进制流
private InputStream inputStream;
// user的setter和getter方法
public void setUser(String user){
this.user = user;
}
public String getUser(){
return this.user;
}
// pass的setter和getter方法
public void setPass(String pass){
this.pass = pass;
}
public String getPass(){
return this.pass;
}
public InputStream getResult(){
return inputStream;
}
public String execute()
throws Exception{
// 判断用户名、密码,生成对应的响应
inputStream = user.equals("crazyit.org") && pass.equals("leegang")
? new ByteArrayInputStream("恭喜你,登录成功!".getBytes("UTF-8"))
: new ByteArrayInputStream("对不起,用户名、密码不匹配!".getBytes("UTF-8"));
return SUCCESS;
}
}
除了一般Action类里常见的内容外,该Action提供了一个返回二进制流的方法getResult(),其返回的二进制流将会直接输出给浏览者,这将使用Result类型来完成。execute()方法将根据浏览者输入的user、pass请求参数来决定生成怎样的响应。
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<package name="lee" extends="struts-default">
<action name="login" class="org.crazyit.app.action.LoginAction">
<result type="stream">
<!-- 指定下载文件的文件类型 -->
<param name="contentType">text/html</param>
<!-- 指定由getResult()方法返回输出结果的InputStream -->
<param name="inputName">result</param>
</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
在struts.xml中配置Action。
使用Stream类型的Result,struts2不用JSP视图页面,直接在Action向浏览者生成指定的响应。
这里为简单起见,暂不涉及创建XMLHttpRequest对象、发送异步请求这些繁琐步骤,直接借助jQuery这个Ajax库来发送异步请求。页面代码如下。
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用stream结果实现Ajax</title>
<script src="${pageContext.request.contextPath}/jquery-1.11.1.js"
type="text/javascript">
</script>
</head>
<body>
<s:form id="loginForm">
<s:textfield name="user" label="用户名"/>
<s:textfield name="pass" label="密码"/>
<tr><td colspan="2">
<input id="loginBn" type="button" value="提交"/>
</td></tr>
</s:form>
<div id="show" style="display:none;">
</div>
<script type="text/javascript">
// 为id为loginBn的按钮绑定事件处理函数
$("#loginBn").click(function(){
$("#show").hide();
// 指定向login发送请求,以id为loginForm表单里各表单控件作为请求参数
$.get("login" , $("#loginForm").serializeArray() ,
// 指定回调函数
function(data , statusText){
$("#show").height(80)
.width(240)
.css("border" , "1px solid black")
.css("border-radius" , "10px")
.css("background-color" , "#efef99")
.css("color" , "#ff0000")
.css("padding" , "20px")
.empty();
$("#show").append("登录结果:" + data + "<br />");
$("#show").show(2000);
},
// 指定服务器响应为html
"html");
});
</script>
</body>
</html>
另外,struts2.2还提供了一个JSON插件,通过该插件可以更简单地完成Ajax开发。