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

3.2 发送请求参数相关推荐

  1. angular ajax get post 参数,AngularJS - $ http.post发送请求参数而不是JSON的任何方式?...

    AngularJS - $ http.post发送请求参数而不是JSON的任何方式? 我有一些旧的代码通过jQuery的post方法发出一个AJAX POST请求,看起来像这样:$.post(&quo ...

  2. PostMan发送请求参数带有路径特殊字符会返回400错误(与URL字符及URL编码值有关)

    目录 一.请求参数中携带URL字符返回400错误 二. 请求参数中携带URL字符返回400错误原因 三.URL字符及对应的URL编码值列表 四.请求参数中携带URL字符转成URL编码值 一.请求参数中 ...

  3. HttpClient4.x中GET方式发送请求参数中文乱码处理

    HttpClient4.x GET 方式发送请求参数中文乱码处理 (非返回结果乱码) 之前尝试对HttpGet对象添加头部字符编码设置均无效,后改用参数字符编码处理后实现请求参数乱码正确处理. Htt ...

  4. Java发送Http请求之——发送请求参数在Body中Get请求

    1.背景要求 发送Get请求,但是请求参数要放在请求body内,所以经过多方查证后整理出来以下代码. 2.POM依赖 <dependency><groupId>org.apac ...

  5. 使用struts2框架中3种客户端向服务端发送请求参数的方式

    1.action属性: 前端参数直接在action属性名之后,如PersonAction?id=1; 在对应的action中加入属性id,必须加对应属性的get(),set()方法,其中属性名应为小写 ...

  6. nodeJs 接收请求参数和发送请求参数

    接收请求: request: (1) req.query (2) 导入中间件:var bodyParser = require('body-parser') req.body 响应: response ...

  7. html action get post请求参数乱码,input type=text 发送请求参数,中文乱码问题

    1.不废话,直接代码如下: teacher.jsp pageEncoding="UTF-8"%> 教师管理页面 课程资源目录: --------------- 作业提交目录: ...

  8. post发送请求参数注意的问题

    转载于:https://www.cnblogs.com/lishidefengchen/p/11090446.html

  9. java后台获取流_java后台发送请求获取数据,并解析json数据

    packagecom.bs.utils;importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.io.Print ...

最新文章

  1. 2017最新整理传智播客JavaEE第49期 基础就业班
  2. 一个通俗易懂的HMM例子
  3. linux无任务内存被占满,centos服务器CPU被GC task占满,程序无内存溢出
  4. 用REDIS实现分布式缓存
  5. nginx搭建流媒体服务器
  6. html 手写字效果,canvas画布实现手写签名效果的示例代码
  7. 虚拟研讨会:.NET的未来在哪里?
  8. 从戈君离开B站,聊聊技术人如何面对期权不踩坑
  9. 中国联通董事李福申辞任
  10. C++语言基础 例程 派生类的声明与构成
  11. 技嘉主板BIOS修改风扇转速设置详细教程
  12. .axf文件_Jlink使用技巧之单独下载HEX文件到单片机
  13. Jzoj4722 跳楼机
  14. 利用条形码生成器在Word 2013中轻松制作条形码的方法
  15. 自动驾驶技术基础——惯导
  16. 目标检测经典论文详解
  17. 安全私人云储存时代 H3C Magic M2脱颖而出
  18. 【云和恩墨大讲堂】黄宸宁 - 一次特殊的 ORA-04030 故障处理
  19. 高德Android 定位SDK示例
  20. PDF删除水印怎么操作

热门文章

  1. tcp state linux,Linux Kernel ‘tcp_rcv_state_process()’函数拒绝服务漏洞
  2. 惊!12306官网又现用户信息泄露?
  3. PHP计算一年有多少周,每周开始日期和结束日期
  4. 31岁清华副教授誓为国产工控软件护航
  5. oracle00312,ORA-00322 ORA-00312 恢复
  6. 中医大2020年7月网考计算机应用基础,2020年7月网络教育统考《计算机应用基础》操作系统应用模拟题试卷2...
  7. Shiro中自定义Realm
  8. docker搭建XXLjob
  9. 【论文阅读】3D-CVF: Generating Joint Camera and LiDAR Features Using Cross-View Spatial Feature Fusion for
  10. 心若无尘,一花一世界,一鸟一天堂