jsp Servlet基礎入門學習篇 四、處理表單數據

發布時間:2007年02月01日      浏覽次數:2222 次
4.1 表單數據概述
   如果你曾經使用過Web搜索引擎,或者浏覽過在線書(shū)店(diàn)、股票價格、機票信息,或許會留意到一(yī)些古怪的URL,比如“http://host/path?user=Marty Hall&origin=bwi&dest=lax”。這個URL中(zhōng)位于問号後面的部分(fēn),即“user=Marty Hall&origin=bwi&dest=lax”,就是表單數據,這是将Web頁面數據發送給服務器程序的最常用方法。對于GET請求,表單數據附加到URL的問号後面(如上例所示);對于POST請求,表單數據用一(yī)個單獨的行發送給服務器。
   以前,從這種形式的數據提取出所需要的表單變量是CGI編程中(zhōng)最麻煩的事情之一(yī)。首先,GET請求和POST請求的數據提取方法不同:對于GET請求,通常要通過QUERY_STRING環境變量提取數據;對于POST請求,則一(yī)般通過标準輸入提取數據。第二,程序員(yuán)必須負責在“&”符号處截斷變量名字-變量值對,再分(fēn)離(lí)出變量名字(等号左邊)和變量值(等号右邊)。第三,必須對變量值進行URL反編碼操作。因爲發送數據的時候,字母和數字以原來的形式發送,但空格被轉換成加号,其他字符被轉換成“%XX”形式,其中(zhōng)XX是十六進制表示的字符ASCII(或者ISO Latin-1)編碼值。例如,如果HTML表單中(zhōng)名爲“users”的域值爲“~hall, ~gates, and ~mcnealy”,則實際向服務器發送的數據爲“users=~hall, ~gates, and ~mcnealy”。最後,即第四個導緻解析表單數據非常困難的原因在于,變量值既可能被省略(如“param1=val1&param2=&param3=val3”),也有可能一(yī)個變量擁有一(yī)個以上的值,即同一(yī)個變量可能出現一(yī)次以上(如“param1=val1&param2=val2&param1=val3”)。
   Java Servlet的好處之一(yī)就在于所有上述解析操作都能夠自動完成。隻需要簡單地調用一(yī)下(xià)HttpServletRequest的getParameter方法、在調用參數中(zhōng)提供表單變量的名字(大(dà)小(xiǎo)寫敏感)即可,而且GET請求和POST請求的處理方法完全相同。
   getParameter方法的返回值是一(yī)個字符串,它是參數中(zhōng)指定的變量名字第一(yī)次出現所對應的值經反編碼得到得字符串(可以直接使用)。如果指定的表單變量存在,但沒有值,getParameter返回空字符串;如果指定的表單變量不存在,則返回null。如果表單變量可能對應多個值,可以用getParameterValues來取代getParameter。getParameterValues能夠返回一(yī)個字符串數組。
   最後,雖然在實際應用中(zhōng)Servlet很可能隻會用到那些已知(zhī)名字的表單變量,但在調試環境中(zhōng),獲得完整的表單變量名字列表往往是很有用的,利用getParamerterNames方法可以方便地實現這一(yī)點。getParamerterNames返回的是一(yī)個Enumeration,其中(zhōng)的每一(yī)項都可以轉換爲調用getParameter的字符串。
   4.2 實例:讀取三個表單變量
   下(xià)面是一(yī)個簡單的例子,它讀取三個表單變量param1、param2和param3,并以HTML列表的形式列出它們的值。請注意,雖然在發送應答内容之前必須指定應答類型(包括内容類型、狀态以及其他HTTP頭信息),但Servlet對何時讀取請求内容卻沒有什麽要求。
   另外(wài),我(wǒ)(wǒ)們也可以很容易地把Servlet做成既能處理GET請求,也能夠處理POST請求,這隻需要在doPost方法中(zhōng)調用doGet方法,或者覆蓋service方法(service方法調用doGet、doPost、doHead等方法)。在實際編程中(zhōng)這是一(yī)種标準的方法,因爲它隻需要很少的額外(wài)工(gōng)作,卻能夠增加客戶端編碼的靈活性。
   如果你習慣用傳統的CGI方法,通過标準輸入讀取POST數據,那麽在Servlet中(zhōng)也有類似的方法,即在HttpServletRequest上調用getReader或者getInputStream,但這種方法對普通的表單變量來說太麻煩。然而,如果是要上載文件,或者POST數據是通過專門的客戶程序而不是HTML表單發送,那麽就要用到這種方法。
   注意用第二種方法讀取POST數據時,不能再用getParameter來讀取這些數據。
   ThreeParams.java
package hall;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class ThreeParams extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "讀取三個請求參數";
out.println(ServletUtilities.headWithTitle(title)
"<BODY>\n"
"<H1 ALIGN=CENTER>" title "</H1>\n"
"<UL>\n"
" <LI>param1: "
request.getParameter("param1") "\n"
" <LI>param2: "
request.getParameter("param2") "\n"
" <LI>param3: "
request.getParameter("param3") "\n"
"</UL>\n"
"</BODY></HTML>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
   4.3 實例:輸出所有的表單數據
   下(xià)面這個例子尋找表單所發送的所有變量名字,并把它們放(fàng)入表格中(zhōng),沒有值或者有多個值的變量都突出顯示。
   首先,程序通過HttpServletRequest的getParameterNames方法得到所有的變量名字,getParameterNames返回的是一(yī)個Enumeration。接下(xià)來,程序用循環遍曆這個Enumeration,通過hasMoreElements确定何時結束循環,利用nextElement得到Enumeration中(zhōng)的各個項。由于nextElement返回的是一(yī)個Object,程序把它轉換成字符串後再用這個字符串來調用getParameterValues。
   getParameterValues返回一(yī)個字符串數組,如果這個數組隻有一(yī)個元素且等于空字符串,說明這個表單變量沒有值,Servlet以斜體(tǐ)形式輸出“No Value”;如果數組元素個數大(dà)于1,說明這個表單變量有多個值,Servlet以HTML列表形式輸出這些值;其他情況下(xià)Servlet直接把變量值放(fàng)入表格。
   ShowParameters.java
   注意,ShowParameters.java用到了前面介紹過的ServletUtilities.java。
package hall;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class ShowParameters extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "讀取所有請求參數";
out.println(ServletUtilities.headWithTitle(title)
"<BODY BGCOLOR=\"#FDF5E6\">\n"
"<H1 ALIGN=CENTER>" title "</H1>\n"
"<TABLE BORDER=1 ALIGN=CENTER>\n"
"<TR BGCOLOR=\"#FFAD00\">\n"
"<TH>參數名字<TH>參數值");
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.println("<TR><TD>" paramName "\n<TD>");
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.print("<I>No Value</I>");
else
out.print(paramValue);
} else {
out.println("<UL>");
for(int i=0; i<paramValues.length; i ) {
out.println("<LI>" paramValues[i]);
}
out.println("</UL>");
}
}
out.println("</TABLE>\n</BODY></HTML>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
   測試表單
   下(xià)面是向上述Servlet發送數據的表單PostForm.html。就像所有包含密碼輸入域的表單一(yī)樣,該表單用POST方法發送數據。我(wǒ)(wǒ)們可以看到,在Servlet中(zhōng)同時實現doGet和doPost這兩種方法爲表單制作帶來了方便。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>示例表單</TITLE>
</HEAD>
<BODY BGCOLOR="#FDF5E6">
<H1 ALIGN="CENTER">用POST方法發送數據的表單</H1>
<FORM ACTION="/servlet/hall.ShowParameters"
METHOD="POST">
Item Number:
<INPUT TYPE="TEXT" NAME="itemNum"><BR>
Quantity:
<INPUT TYPE="TEXT" NAME="quantity"><BR>
Price Each:
<INPUT TYPE="TEXT" NAME="price" VALUE="[GV_contentText]quot;><BR>
<HR>
First Name:
<INPUT TYPE="TEXT" NAME="firstName"><BR>
Last Name:
<INPUT TYPE="TEXT" NAME="lastName"><BR>
Middle Initial:
<INPUT TYPE="TEXT" NAME="initial"><BR>
Shipping Address:
<TEXTAREA NAME="address" ROWS=3 COLS=40></TEXTAREA><BR>
Credit Card:<BR>
<INPUT TYPE="RADIO" NAME="cardType"
VALUE="Visa">Visa<BR>
<INPUT TYPE="RADIO" NAME="cardType"
VALUE="Master Card">Master Card<BR>
<INPUT TYPE="RADIO" NAME="cardType"
VALUE="Amex">American Express<BR>
<INPUT TYPE="RADIO" NAME="cardType"
VALUE="Discover">Discover<BR>
<INPUT TYPE="RADIO" NAME="cardType"
VALUE="Java SmartCard">Java SmartCard<BR>
Credit Card Number:
<INPUT TYPE="PASSWORD" NAME="cardNum"><BR>
Repeat Credit Card Number:
<INPUT TYPE="PASSWORD" NAME="cardNum"><BR><BR>
<CENTER>
<INPUT TYPE="SUBMIT" VALUE="Submit Order">
</CENTER>
</FORM>
</BODY>
</HTML>
文章來源:http://www.jsping.com/jiaocheng/jsp-jichu/4007.html
免責聲明:本站相關技術文章信息部分(fēn)來自網絡,目的主要是傳播更多信息,如果您認爲本站的某些信息侵犯了您的版權,請與我(wǒ)(wǒ)們聯系,我(wǒ)(wǒ)們會即時妥善的處理,謝謝合作!