站长百科 | 数字化技能提升教程 数字化时代生存宝典
首页
数字化百科
电子书
建站程序
开发
服务器
办公软件
开发教程
服务器教程
软件使用教程
运营教程
热门电子书
WordPress教程
宝塔面板教程
CSS教程
Shopify教程
导航
程序频道
推广频道
网赚频道
人物频道
网站程序
网页制作
云计算
服务器
CMS
论坛
网店
虚拟主机
cPanel
网址导航
WIKI使用导航
WIKI首页
最新资讯
网站程序
站长人物
页面分类
使用帮助
编辑测试
创建条目
网站地图
站长百科导航
站长百科
主机侦探
IDCtalk云说
跨境电商导航
WordPress啦
站长专题
网站推广
网站程序
网站赚钱
虚拟主机
cPanel
网址导航专题
云计算
微博营销
虚拟主机管理系统
开放平台
WIKI程序与应用
美国十大主机
编辑“
Ajax- 与服务器通信2
”
人物百科
|
营销百科
|
网赚百科
|
站长工具
|
网站程序
|
域名主机
|
互联网公司
|
分类索引
跳转至:
导航
、
搜索
警告:
您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您
登录
或
创建
一个账户,您的编辑将归属于您的用户名,且将享受其他好处。
反垃圾检查。
不要
加入这个!
<span style="text-align:center; border:1px solid #000; float:right; padding:6px;"><strong>导航:</strong> [[Ajax学习教程#Ajax学习教程|上一页]] | {{template:开发语言导航}}</span> <div style="clear:both;"></div> 到此为止,你已经了解了如何使用Ajax技术向服务器发送请求,也知道了客户可以采用多种方法解析服务器的响应。前面的例子中只缺少一个内容,就是你尚未将任何数据作为请求的一部分发送给服务器。在大多数情况下,向服务器发送一个请求而没有任何请求参数是没有什么意义的。如果没有请求参数,服务器就得不到上下文数据,也无法根据上下文数据为客户创建“个性化”的响应,实际上,服务器会向每一个客户发送同样的响应。 要想充分发挥Ajax技术的强大功能,这要求你向服务器发送一些上下文数据。假设有一个输入表单,其中包含需要输入邮件地址的部分。根据用户输入的ZIP编码,可以使用Ajax技术预填相应的城市名。当然,要想查找ZIP编码对应的城市,服务器首先需要知道用户输入的ZIP编码。 你需要以某种方式将用户输入的ZIP编码值传递给服务器。幸运的是,XMLHttpRequest对象的工作与你以往惯用的HTTP技术(GET和POST)是一样的。 GET方法把值作为名/值对放在请求URL中传递。资源URL的最后有一个问号(?),问号后面就是名/值对。名/值对采用name=value的形式,各个名/值对之间用与号(&)分隔。 下面是GET请求的一个例子。这个请求向localhost服务器上的yourApp应用发送了两个参数:firstName和middleName。需要注意,资源URL和参数集之间用问号分隔,firstName和middleName之间用与号(&)分隔:<br> <nowiki>http://localhost/yourApp?firstName=Adam&middleName=Christopher </nowiki><br> 服务器知道如何获取URL中的命名参数。当前大多数服务器端编程环境都提供了简单的API,使你能很容易地访问命名参数。<br> 采用POST方法向服务器发送命名参数时,与采用GET方法几乎是一样的。类似于GET方法,POST方法会把参数编码为名/值对,形式为name=value,每个名/值对之间也用与号(&)分隔。这两种方法的主要区别在于,POST方法将参数串放在请求体中发送,而GET方法是将参数追加到URL中发送。<br> 如果数据处理不改变数据模型的状态,HTML使用规约理论上推荐采用GET方法,从这可以看出,获取数据时应当使用GET方法。如果因为存储、更新数据,或者发送了电子邮件,操作改变了数据模型的状态,这时建议使用POST方法。<br> 每个方法都有各自特有的优点。由于GET请求的参数编码到请求URL中,所以可以在浏览器中为该URL建立书签,以后就能很容易地重新请求。不过,如果是异步请求就没有什么用。从发送到服务器的数据量来讲,POST方法更为灵活。使用GET请求所能发送的数据量通常是固定的,因浏览器不同而有所差异,而POST方法可以发送任意量的数据。<br> HTML form元素允许通过将form元素的method属性设置为GET或POST来指定所需的方法。在提交表单时,form元素自动根据其method属性的规则对input元素的数据进行编码。XMLHttpRequest对象没有这种内置行为。相反,要由开发人员使用JavaScript创建查询串,其中包含的数据要作为请求的一部分发送给服务器。不论使用的是GET请求还是POST请求,创建查询串的技术是一样的。惟一的区别是,当使用GET发送请求时,查询串会追加到请求URL中,而使用POST方法时,则在调用XMLHttpRequest对象的send()方法时发送查询串。<br> 图3-4显示了一个示例页面,展示了如何向服务器发送请求参数。这是一个简单的输入表单,要求输入名、姓和生日。这个表单有两个按钮,每个按钮都会向服务器发送名、姓和生日数据,不过一个使用GET方法,另一个使用POST方法。服务器以回显输入数据作为响应。在浏览器在页面上打印出服务器的响应时,请求响应周期结束。<br> [[Image:Image007.jpg]] 图3-4 浏览器使用GET或POST方法发送输入数据,服务器回显输入数据作为响应 <br> 代码清单3-7显示了getAndPostExample.html,代码清单3-8显示了向浏览器回显名、姓和生日数据的Java servlet。<br> 代码清单3-7 getAndPostExample.html<br> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><br> <html xmlns="http://www.w3.org/1999/xhtml"><br> <head><br> <nowiki><title>Sending Request Data Using GET and POST</title></nowiki><br> <nowiki><script type="text/javascript"></nowiki><br> <nowiki>var xmlHttp;</nowiki><br> function createXMLHttpRequest() {<br> if (window.ActiveXObject) {<br> xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br> }<br> else if (window.XMLHttpRequest) {<br> xmlHttp = new XMLHttpRequest();<br> }<br> }<br> function createQueryString() {<br> var firstName = document.getElementById("firstName").value;<br> var middleName = document.getElementById("middleName").value;<br> var birthday = document.getElementById("birthday").value;<br> var queryString = "firstName=" + firstName + "&middleName=" + middleName<br> + "&birthday=" + birthday;<br> return queryString;<br> }<br> function doRequestUsingGET() {<br> createXMLHttpRequest();<br> var queryString = "GetAndPostExample?";<br> queryString = queryString + createQueryString()<br> + "&timeStamp=" + new Date().getTime();<br> xmlHttp.onreadystatechange = handleStateChange;<br> xmlHttp.open("GET", queryString, true);<br> xmlHttp.send(null);<br> }<br> function doRequestUsingPOST() {<br> createXMLHttpRequest();<br> var url = "GetAndPostExample?timeStamp=" + new Date().getTime();<br> var queryString = createQueryString();<br> xmlHttp.open("POST", url, true);<br> xmlHttp.onreadystatechange = handleStateChange;<br> xmlHttp.setRequestHeader("Content-Type",<br> "application/x-www-form-urlencoded;");<br> xmlHttp.send(queryString);<br> }<br> function handleStateChange() {<br> if(xmlHttp.readyState == 4) {<br> if(xmlHttp.status == 200) {<br> parseResults();<br> }<br> }<br> }<br> function parseResults() {<br> var responseDiv = document.getElementById("serverResponse");<br> if(responseDiv.hasChildNodes()) {<br> responseDiv.removeChild(responseDiv.childNodes[0]);<br> }<br> var responseText = document.createTextNode(xmlHttp.responseText);<br> responseDiv.appendChild(responseText);<br> }<br> </script><br> </head><br> <body><br> <nowiki><h1>Enter your first name, middle name, and birthday:</h1></nowiki><br> <nowiki><table></nowiki><br> <nowiki> <tbody></nowiki><br> <nowiki><tr></nowiki><br> <nowiki> <td>First name:</td></nowiki><br> <nowiki><td><input type="text" id="firstName"/></nowiki><br> <nowiki></tr></nowiki><br> <nowiki><tr></nowiki><br> <nowiki><td>Middle name:</td></nowiki><br> <nowiki><td><input type="text" id="middleName"/></nowiki><br> <nowiki></tr></nowiki><br> <nowiki><tr></nowiki><br> <nowiki><td>Birthday:</td></nowiki><br> <nowiki><td><input type="text" id="birthday"/></nowiki><br> <nowiki></tr><nowiki></nowiki><br> <nowiki></tbody><nowiki></nowiki><br> <nowiki></table><nowiki></nowiki><br> <nowiki><form action="#"><nowiki></nowiki><br> <nowiki><input type="button" value="Send parameters using GET"</nowiki><br> <nowiki>onclick="doRequestUsingGET();"/></nowiki><br> <nowiki><br/><br/></nowiki><br> <nowiki><input type="button" value="Send parameters using POST"</nowiki><br> <nowiki>onclick="doRequestUsingPOST();"/></nowiki><br> <nowiki></form></nowiki><br> <nowiki><br/></nowiki><br> <nowiki><h2>Server Response:</h2></nowiki><br> <nowiki><div id="serverResponse"></div></nowiki><br> </body><br> </html><br> 代码清单3-8 向浏览器回显名、姓和生日 package ajaxbook.chap3; <br> import java.io.*;<br> import java.net.*;<br> import javax.servlet.*;<br> import javax.servlet.http.*;<br> public class GetAndPostExample extends HttpServlet {<br> protected void processRequest(HttpServletRequest request,<br> HttpServletResponse response, String method)<br> throws ServletException, IOException {<br> //Set content type of the response to text/xml<br> response.setContentType("text/xml");<br> //Get the user's input<br> String firstName = request.getParameter("firstName");<br> String middleName = request.getParameter("middleName");<br> String birthday = request.getParameter("birthday");<br> //Create the response text<br> String responseText = "Hello " + firstName + " " + middleName<br> + ". Your birthday is " + birthday + "."<br> + " [Method: " + method + "]";<br> //Write the response back to the browser<br> PrintWriter out = response.getWriter();<br> out.println(responseText);<br> //Close the writer<br> out.close();<br> }<br> protected void doGet(HttpServletRequest request, HttpServletResponse response)<br> throws ServletException, IOException {<br> //Process the request in method processRequest<br> processRequest(request, response, "GET");<br> }<br> protected void doPost(HttpServletRequest request, HttpServletResponse response)<br> throws ServletException, IOException {<br> //Process the request in method processRequest<br> processRequest(request, response, "POST");<br> }<br> } <br> 下面先来分析服务器端代码。这个例子使用了Java servlet来处理请求,不过也可以使用任何其他服务器端技术,如PHP、CGI或.NET。Java servlet必须定义一个doGet方法和一个doPost方法,每个方法根据请求方法(GET或POST)来调用。在这个例子中,doGet和doPost都调用同样的方法processRequest来处理请求。<br> processRequest方法先把响应的内容类型设置为text/xml,尽管在这个例子中并没有真正用到XML。通过使用getParameter方法从request对象获得3个输入字段。根据名、姓和生日,以及请求方法的类型,会建立一个简单的语句。这个语句将写至响应输出流,最后响应输出流关闭。<br> 浏览器端JavaScript与前面的例子同样是类似的,不过这里稍稍增加了几个技巧。这里有一个工具函数createQueryString负责将输入参数编码为查询串。createQueryString函数只是获取名、姓和生日的输入值,并将它们追加为名/值对,每个名/值对之间由与号(&)分隔。这个函数会返回查询串,以便GET和POST操作重用。<br> 点击Send Parameters Using GET(使用GET方法发送参数)按钮将调用doRequestUsingGET函数。这个函数与前面例子中的许多函数一样,先调用创建XMLHttpRequest对象实例的函数。接下来,对输入值编码,创建查询串。<br> 在这个例子中,请求端点是名为GetAndPostExample的servlet。在建立查询串时,要把createQueryString函数返回的查询串与请求端点连接,中间用问号分隔。<br> JavaScript仍与前面看到的类似。XMLHttpRequest对象的onreadystatechange属性设置为要使用handleStateChange函数。open()方法指定这是一个GET请求,并指定了端点URL,在这里端点URL中包含有编码的参数。send()方法将请求发送给服务器,handleSta- teChange函数处理服务器响应。<br> 当请求成功完成时,handleStateChange函数将调用parseResults函数。parseResults函数获取div元素,其中包含服务器的响应,并把它保存在局部变量responseDiv中。使用responseDiv的removeChild方法先将以前的服务器结果删除。最后,创建包含服务器响应的新文本节点,并将这个文本节点追加到responseDiv。<br> 使用POST方法而不是GET方法基本上是一样的,只是请求参数发送给服务器的方式不同。应该记得,使用GET时,名/值对会追加到目标URL。POST方法则把同样的查询串作为请求体的一部分发送。<br> 点击Send Parameters Using POST(使用POST方法发送参数)按钮将调用doRequest- UsingPOST函数。类似于doRequestUsingGET函数,它先创建XMLHttpRequest对象的一个实例,脚本再创建查询串,其中包含要发送给服务器的参数。需要注意,查询串现在并不连接到目标URL。<br> 接下来调用XMLHttpRequest对象的open()方法,这一次指定请求方法是POST,另外指定了没有追加名/值对的“原”目标URL。onreadystatechange属性设置为handleStateCh- ange函数,所以响应会以与GET方法中相同的方式得到处理。为了确保服务器知道请求体中有请求参数,需要调用setRequestHeader,将Content-Type值设置为application/x- www-form-urlencoded。最后,调用send()方法,并把查询串作为参数传递给这个方法。<br> 点击两个按钮的结果是一样的。页面上会显示一个串,其中包括指定的名、姓和生日,另外还会显示所用请求方法的类型。<br> 为什么要把时间戳追加到目标URL?<br> 在某些情况下,有些浏览器会把多个XMLHttpRequest请求的结果缓存在同一个URL。如果对每个请求的响应不同,这就会带来不好的结果。把当前时间戳追加到URL的最后,就能确保URL的惟一性,从而避免浏览器缓存结果。<br> == 请求参数作为XML发送 == 与几年前相比,当前浏览器上JavaScript的兼容性有了长足的进步,已经不可同日而语,再加上越来越成熟的JavaScript开发工具和技术,你可以决定把Web浏览器作为开发平台。并不只是依赖于浏览器来看待模型—视图—控制器模式中的视图,还可以用JavaScript实现部分业务模型。可以使用Ajax技术把模型中的变化持久存储到后台服务器。如果模型放在浏览器上,模型的变化可以一齐传递到服务器,从而减少对服务器的远程调用次数,还可能提高性能。<br> 如果只是使用一个包含名/值对的简单查询串,这可能不够健壮,不足以向服务器传递大量复杂的模型变化。更好的解决方案是将模型的变化作为XML发送到服务器。怎么向服务器发送XML呢?<br> 可以把XML作为请求体的一部分发送到服务器,这与POST请求中将查询串作为请求体的一部分进行发送异曲同工。服务器可以从请求体读到XML,并加以处理。<br> 下面的例子展示了对于一个Ajax请求如何向服务器发送XML。图3-5显示了这个页面,其中有一个简单的选择框,用户可以选择宠物的类型。这是一个相当简化的例子,但是由此可以了解如何向服务器发送XML。<br> [[Image:Image008.jpg]] 图3-5 选择框中选中的项将作为XML发送到服务器<br> 代码清单3-9显示了postingXML.html。<br> 代码清单3-9 postingXML.html<br> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br> <nowiki> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><.nowiki><br> <nowiki><html xmlns="http://www.w3.org/1999/xhtml"><.nowiki><br> <head><br> <nowiki><title>Sending an XML Request</title><.nowiki><br> <nowiki><script type="text/javascript"><.nowiki><br> <nowiki>var xmlHttp;<.nowiki><br> <nowiki>function createXMLHttpRequest() {<.nowiki><br> if (window.ActiveXObject) {<br> xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br> }<br> else if (window.XMLHttpRequest) {<br> xmlHttp = new XMLHttpRequest();<br> }<br> }<br> function createXML() {<br> var xml = "<pets>";<br> var options = document.getElementById("petTypes").childNodes;<br> var option = null;<br> for(var i = 0; i < options.length; i++) {<br> option = options[i];<br> if(option.selected) {<br> xml = xml + "<type>" + option.value + "<\/type>";<br> }<br> }<br> xml = xml + "<\/pets>";<br> return xml;<br> }<br> function sendPetTypes() {<br> createXMLHttpRequest();<br> var xml = createXML();<br> var url = "PostingXMLExample?timeStamp=" + new Date().getTime();<br> xmlHttp.open("POST", url, true);<br> xmlHttp.onreadystatechange = handleStateChange;<br> xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");<br> xmlHttp.send(xml);<br> }<br> function handleStateChange() {<br> if(xmlHttp.readyState == 4) {<br> if(xmlHttp.status == 200) {<br> parseResults();<br> }<br> }<br> }<br> function parseResults() {<br> var responseDiv = document.getElementById("serverResponse");<br> if(responseDiv.hasChildNodes()) {<br> responseDiv.removeChild(responseDiv.childNodes[0]);<br> }<br> var responseText = document.createTextNode(xmlHttp.responseText);<br> responseDiv.appendChild(responseText);<br> }<br> </script><br> </head><br> <body><br> <nowiki><h1>Select the types of pets in your home:</h1></nowiki><br> <nowiki><form action="#"></nowiki><br> <nowiki><select id="petTypes" size="6" multiple="true"></nowiki><br> <nowiki><option value="cats">Cats</option></nowiki><br> <nowiki><option value="dogs">Dogs</option></nowiki><br> <nowiki><option value="fish">Fish</option></nowiki><br> <nowiki><option value="birds">Birds</option></nowiki><br> <nowiki><option value="hamsters">Hamsters</option></nowiki><br> <nowiki><option value="rabbits">Rabbits</option></nowiki><br> <nowiki></select></nowiki><br> <nowiki><br/><br/></nowiki><br> <nowiki><input type="button" value="Submit Pets" onclick="sendPetTypes();"/></nowiki><br> <nowiki></form></nowiki><br> <nowiki><h2>Server Response:</h2></nowiki><br> <nowiki><div id="serverResponse"></div></nowiki><br> </body><br> </html><br> 这个例子与前面的POST例子基本上是一样的。区别在于,不是发送由名/值对组成的查询串,而是向服务器发送XML串。 <br> 点击表单上的Submit Pets(提交宠物)按钮将调用sendPetTypes函数。类似于前面的例子,这个函数首先创建XMLHttpRequest对象的一个实例,然后调用名为createXML的辅助函数,它根据所选的宠物类型建立XML串。<br> 函数createXML使用document.getElementbyId方法获得select元素的引用,然后迭代处理所有option子元素,对于选中的每个option元素依据所选宠物类型创建XML标记,并逐个追加到XML中。循环结束时,要在返回到调用函数(sendPetTypes)之前向XML串追加结束pets标记。<br> 一旦得到了XML串,sendPetTypes函数继续为请求准备XMLHttpObject,然后把XML串指定为send()方法的参数,从而将XML发送到服务器。<br> 在createXML方法中,为什么结束标记中斜线前面有一个反斜线?<br> SGML规约(HTML就是从SGML发展来的)中提供了一个技巧,利用这个技巧可以识别出script元素中的结束标记,但是其他内容(如开始标记和注释)则不能识别。使用反斜线可以避免把串解析为标记。即使没有反斜线,大多数浏览器也能安全地处理,但是根据严格的XHTML标准,应该使用反斜线。 <br> 聪明的读者可能注意到,根据XMLHttpRequest对象的文档,send()方法可以将串和XML文档对象实例作为参数。那么,这个例子为什么使用串连接来创建XML,而不是直接创建文档和元素对象呢?遗憾的是,对于从头构建文档对象,目前还没有跨浏览器的技术。IE通过ActiveX对象提供这个功能,Mozilla浏览器则通过本地JavaScript对象来提供,其他浏览器可能根本不支持,也可能通过其他途径来支持这个功能。<br> 读取XML的服务器端代码如代码清单3-10所示,这个代码稍有些复杂。在此使用了Java servlet来读取请求,并解析XML串,不过你也可以使用其他的服务器端技术。<br> 一旦收到XMLHttpRequest对象的请求,就会调用这个servlet的doPost方法。doPost方法使用名为readXMLFromRequestBody的辅助方法从请求体中抽取XML,然后使用JAXP接口将XML串转换为Document对象。<br> 注意,Document对象是W3C指定的Document接口的一个实例。因此,它与浏览器的Document对象有着同样的方法,如getElementsByTagName。可以使用这个方法来得到文档中所有type元素的列表。对于文档中的每个type元素,会得到文本值(应该记得,文本值是type元素的第一个子节点),并逐个追加到串中。处理完所有type元素后,响应串写回到浏览器。<br> 代码清单3-10 PostingXMLExample.java<br> package ajaxbook.chap3;<br> import java.io.*;<br> import javax.servlet.*;<br> import javax.servlet.http.*;<br> import javax.xml.parsers.DocumentBuilderFactory;<br> import javax.xml.parsers.ParserConfigurationException;<br> import org.w3c.dom.Document;<br> import org.w3c.dom.NodeList;<br> import org.xml.sax.SAXException;<br> public class PostingXMLExample extends HttpServlet {<br> protected void doPost(HttpServletRequest request, HttpServletResponse response)<br> throws ServletException, IOException {<br> String xml = readXMLFromRequestBody(request);<br> Document xmlDoc = null;<br> try {<br> xmlDoc =<br> DocumentBuilderFactory.newInstance().newDocumentBuilder()<br> .parse(new ByteArrayInputStream(xml.getBytes()));<br> }<br> catch(ParserConfigurationException e) {<br> System.out.println("ParserConfigurationException: " + e);<br> }<br> catch(SAXException e) {<br> System.out.println("SAXException: " + e);<br> }<br> /* Note how the Java implementation of the W3C DOM has the same methods<br> * as the JavaScript implementation, such as getElementsByTagName and<br> * getNodeValue.<br> */<br> NodeList selectedPetTypes = xmlDoc.getElementsByTagName("type");<br> String type = null;<br> String responseText = "Selected Pets: ";<br> for(int i = 0; i < selectedPetTypes.getLength(); i++) {<br> type = selectedPetTypes.item(i).getFirstChild().getNodeValue();<br> responseText = responseText + " " + type;<br> }<br> response.setContentType("text/xml");<br> response.getWriter().print(responseText);<br> }<br> private String readXMLFromRequestBody(HttpServletRequest request){<br> StringBuffer xml = new StringBuffer();<br> String line = null;<br> try {<br> BufferedReader reader = request.getReader();<br> while((line = reader.readLine()) != null) {<br> xml.append(line);<br> }<br> }<br> catch(Exception e) {<br> System.out.println("Error reading XML: " + e.toString());<br> }<br> return xml.toString();<br> }<br> } <br> == 使用JSON向服务器发送数据 == 做了这么多,你已经能更顺手地使用JavaScript了,也许在考虑把更多的模型信息放在浏览器上。不过,看过前面的例子后(使用XML向服务器发送复杂的数据结构),你可能会改变主意。通过串连接来创建XML串并不好,这也不是用来生成或修改XML数据结构的健壮技术。<br> '''JSON概述'''<br> XML的一个替代方法是JSON,可以在www.json.org找到。JSON是一种文本格式,它独立于具体语言,但是使用了与C系列语言(如C、C#、JavaScript等)类似的约定。JSON建立在以下两种数据结构基础上,当前几乎所有编程语言都支持这两种数据结构:<br> l 名/值对集合。在当前编程语言中,这实现为一个对象、记录或字典。<br> l 值的有序表,这通常实现为一个数组。<br> 因为这些结构得到了如此众多编程语言的支持,所以JSON是一个理想的选择,可以作为异构系统之间的一种数据互换格式。另外,由于JSON是基于标准JavaScript的子集,所以在所有当前Web浏览器上都应该是兼容的。<br> JSON对象是名/值对的无序集合。对象以 { 开始,以 } 结束,名/值对用冒号分隔。JSON数组是一个有序的值集合,以[ 开始,以 ] 结束,数组中的值用逗号分隔。值可以是串(用双引号引起)、数值、true或false、对象,或者是数组,因此结构可以嵌套。图3-6以图形方式很好地描述了JSON对象的标记。<br> [[Image:Image009.jpg]] 图3-6 JSON对象结构的图形化表示(摘自www.json.org)<br> 请考虑employee对象的简单例子。employee对象可能包含名、姓、员工号和职位等数据。使用JSON,可以如下表示employee对象实例: <br> var employee = {<br> "firstName" : John<br> , "lastName" : Doe<br> , "employeeNumber" : 123<br> , "title" : "Accountant"<br> }<br> 然后可以使用标准点记法使用对象的属性,如下所示:<br> var lastName = employee.lastName; //Access the last name<br> var title = employee.title; //Access the title<br> employee.employeeNumber = 456; //Change the employee number<br> JSON有一点很引以为豪,这就是它是一个轻量级的数据互换格式。如果用XML来描述同样的employee对象,可能如下所示:<br> <employee><br> <firstName>John</firstName><br> <lastName>Doe</lastName><br> <employeeNumber>123</employeeNumber><br> <title>Accountant</title><br> </employee><br> 显然,JSON编码比XML编码简短。JSON编码比较小,所以如果在网络上发送大量数据,可能会带来显著的性能差异。<br> www.json.org网站列出了至少与其他编程语言的14种绑定,这说明,不论在服务器端使用何种技术,都能通过JSON与浏览器通信。<br> 使用JSON的示例<br> 下面是一个简单的例子,展示了如何使用JSON将JavaScript对象转换为串格式,并使用Ajax技术将这个串发送到服务器,然后服务器根据这个串创建一个对象。这个例子中没有业务逻辑,也几乎没有用户交互,它强调的是客户端和服务器端的JSON技术。图3-7显示了一个“字符串化的”Car对象。<br> [[Image:Image010.jpg]] 图3-7 “字符串化的”Car对象<br> 因为这个例子几乎与前面的POST例子完全相同,所以我们只关注JSON特定的技术。点击表单上的按钮将调用doJSON函数。这个函数首先调用getCarObject函数来返回一个新的Car对象实例,然后使用JSON JavaScript库(可以从www.json.org免费得到)将Car对象转换为JSON串,再在警告框中显示这个串。接下来使用XMLHttpRequest对象将JSON编码的Car对象发送到服务器。<br> 因为有可以免费得到的JSON-Java绑定库,所以编写Java servlet来为JSON请求提供服务相当简单。更妙的是,由于对每种服务器端技术都有相应的JSON绑定,所以可以使用任何服务器端技术实现这个例子。 [[Image:Image011.jpg]] <br>JSONExample servlet的doPost方法为JSON请求提供服务。它首先调用readJSONStr- ingFromRequestBody方法从请求体获得JSON串,然后创建JSONObject的一个实例,向JSONObject构造函数提供JSON串。JSONObject在对象创建时自动解析JSON串。一旦创建了JSONObject,就可以使用各个get方法来获得你感兴趣的对象属性。<br> 这里使用getString和getInt方法来获取year、make、model和color属性。这些属性连接起来构成一个串返回给浏览器,并在页面上显示。图3-8显示了读取JSON对象之后的服务器响应。<br> 代码清单3-11显示了jsonExample.html,代码清单3-12显示了JSONExample.java。<br> 代码清单3-11 jsonExample.html<br> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"<br> <nowiki> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"></nowiki><br> <html xmlns="http://www.w3.org/1999/xhtml"><br> <head><br> <nowiki><title>JSON Example</title></nowiki><br> <nowiki><script type="text/javascript" src="json.js"></script></nowiki><br> <nowiki><script type="text/javascript"></nowiki><br> <nowiki>var xmlHttp;</nowiki><br> function createXMLHttpRequest() {<br> if (window.ActiveXObject) {<br> xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br> }<br> else if (window.XMLHttpRequest) {<br> xmlHttp = new XMLHttpRequest();<br> }<br> }<br> function doJSON() {<br> var car = getCarObject();<br> //Use the JSON JavaScript library to stringify the Car object<br> var carAsJSON = JSON.stringify(car);<br> alert("Car object as JSON:\n " + carAsJSON);<br> var url = "JSONExample?timeStamp=" + new Date().getTime();<br> createXMLHttpRequest();<br> xmlHttp.open("POST", url, true);<br> xmlHttp.onreadystatechange = handleStateChange;<br> xmlHttp.setRequestHeader("Content-Type",<br> "application/x-www-form-urlencoded;");<br> xmlHttp.send(carAsJSON);<br> }<br> function handleStateChange() {<br> if(xmlHttp.readyState == 4) {<br> if(xmlHttp.status == 200) {<br> parseResults();<br> }<br> }<br> }<br> function parseResults() {<br> var responseDiv = document.getElementById("serverResponse");<br> if(responseDiv.hasChildNodes()) {<br> responseDiv.removeChild(responseDiv.childNodes[0]);<br> }<br> var responseText = document.createTextNode(xmlHttp.responseText);<br> responseDiv.appendChild(responseText);<br> }<br> function getCarObject() {<br> return new Car("Dodge", "Coronet R/T", 1968, "yellow");<br> }<br> function Car(make, model, year, color) {<br> this.make = make;<br> this.model = model;<br> this.year = year;<br> this.color = color;<br> }<br> </script><br> </head><br> <body><br> <nowiki><br/><br/></nowiki><br> <nowiki><form action="#"></nowiki><br> <nowiki><input type="button" value="Click here to send JSON data to the server"</nowiki><br> <nowiki>onclick="doJSON();"/></nowiki><br> <nowiki></form></nowiki><br> <nowiki><h2>Server Response:</h2></nowiki><br> <nowiki><div id="serverResponse"></div></nowiki><br> </body><br> </html><br> 代码清单3-12 JSONExample.java<br> package ajaxbook.chap3;<br> import java.io.*;<br> import java.net.*;<br> import java.text.ParseException;<br> import javax.servlet.*;<br> import javax.servlet.http.*;<br> import org.json.JSONObject;<br> public class JSONExample extends HttpServlet {<br> protected void doPost(HttpServletRequest request, HttpServletResponse response)<br> throws ServletException, IOException {<br> String json = readJSONStringFromRequestBody(request);<br> //Use the JSON-Java binding library to create a JSON object in Java<br> JSONObject jsonObject = null;<br> try {<br> jsonObject = new JSONObject(json);<br> }<br> catch(ParseException pe) {<br> System.out.println("ParseException: " + pe.toString());<br> }<br> String responseText = "You have a " + jsonObject.getInt("year") + " "<br> + jsonObject.getString("make") + " " + jsonObject.getString("model")<br> + " " + " that is " + jsonObject.getString("color") + " in color.";<br> response.setContentType("text/xml");<br> response.getWriter().print(responseText);<br> }<br> private String readJSONStringFromRequestBody(HttpServletRequest request){<br> StringBuffer json = new StringBuffer();<br> String line = null;<br> try {<br> BufferedReader reader = request.getReader();<br> while((line = reader.readLine()) != null) {<br> json.append(line);<br> }<br> }<br> catch(Exception e) {<br> System.out.println("Error reading JSON string: " + e.toString());<br> }<br> return json.toString();<br> }<br> }<br> [[category:Ajax]]
摘要:
请注意,您对站长百科的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。
您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅
Wordpress-mediawiki:版权
的细节)。
未经许可,请勿提交受版权保护的作品!
取消
编辑帮助
(在新窗口中打开)
本页使用的模板:
模板:开发语言导航
(
编辑
)