Ajax - 发送请求参数-servlet例子

 

到此为止,你已经了解了如何使用Ajax技术向服务器发送请求,也知道了客户可以采用多种方法解析服务器的响应。前面的例子中只缺少一个内容,就是你尚未将任何数据作为请求的一部分发送给服务器。在大多数情况下,向服务器发送一个请求而没有任何请求参数是没有什么意义的。如果没有请求参数,服务器就得不到上下文数据,也无法根据上下文数据为客户创建“个性化”的响应,实际上,服务器会向每一个客户发送同样的响应。
要想充分发挥Ajax技术的强大功能,这要求你向服务器发送一些上下文数据。假设有一个输入表单,其中包含需要输入邮件地址的部分。根据用户输入的ZIP编码,可以使用Ajax技术预填相应的城市名。当然,要想查找ZIP编码对应的城市,服务器首先需要知道用户输入的ZIP编码。
你需要以某种方式将用户输入的ZIP编码值传递给服务器。幸运的是,XMLHttpRequest对象的工作与你以往惯用的HTTP技术( GETPOST)是一样的。
简单点来说就是用get方法链接后面要带参数跟值,post就不用
GET方法把值作为名/值对放在请求URL中传递。资源URL的最后有一个问号( ?),问号后面就是名/值对。名/值对采用 name=value的形式,各个名/值对之间用与号( &)分隔。
下面是 GET请求的一个例子。这个请求向 localhost服务器上的 yourApp应用发送了 两个参数: firstNamemiddleName需要注意,资源 URL 和参数集之间用问号分隔firstNamemiddleName之间用与号( &)分隔:
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属性设置为 GETPOST来指定所需的方法。在提交表单时, 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");
    }
}
          在web.xml中配置servlet
         <servlet>
                    <servlet-name>GetAndPostSample</servlet-name>
                   <servlet-class>ajaxbook.chap3.GetAndPostExample</servlet-class>      //类,如果有包,要加上包
         </servlet>
         <servlet-mapping>
                   <servlet-name>GetAndPostSample</servlet-name>        //名字要与上面对应
                  <url-pattern>/GetAndPostExample</url-pattern>                 //url模式
         </servlet-mapping>
下面先来分析服务器端代码。这个例子使用了Java servlet来处理请求,不过也可以使用 任何其他服务器端技术,如 PHP CGI .NET Java servlet 必须定义一个 doGet 方法和一个 doPost 方法,每个方法根据请求方法( GET POST )来调用。在这个例子中, doGet doPost都调用同样的方法 processRequest来处理请求。
processRequest方法先把响应的内容类型设置为text/xml,尽管在这个例子中并没有真正用到XML。通过使用 getParameter方法从 request对象获得3个输入字段。根据名、姓和生日,以及请求方法的类型,会建立一个简单的语句。这个语句将写至响应输出流,最后响应输出流关闭。
浏览器端JavaScript与前面的例子同样是类似的,不过这里稍稍增加了几个技巧。这里有一个工具函数 createQueryString负责将输入参数编码为查询串。 createQueryString函数只是获取名、姓和生日的输入值,并将它们追加为名/值对,每个名/值对之间由与号( &)分隔。这个函数会返回查询串,以便 GETPOST操作重用。
点击 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中。使用 responseDivremoveChild方法先将以前的服务器结果删除。最后,创建包含服务器响应的新文本节点,并将这个文本节点追加到 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的惟一性,从而避免浏览器缓存结果。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值