站长中国
设为首页 | 站长论坛

站长论坛 站长下载
您所在的位置: 站长中国 > 站长学院 > 网络编程 > JSP专区 >  正文

四、处理表单数据
  2007年10月22日16:26:21  评论(0条) 字体:[ ]
相关热点: 处理 表单 BR INPUT TYPE NAME 请求 变量 import

  4.1 表单数据概述

  如果你曾经使用过Web搜索引擎,或者浏览过在线书店、股票价格、机票信息,或许会留意到一些古怪的URL,比如“http://host/path? user=Marty+Hall&origin=bwi&dest=lax”。这个URL中位于问号后面的部分,即“user= Marty+Hall&origin=bwi&dest=lax”,就是表单数据,这是将Web页面数据发送给服务器程序的最常用方法。对于GET请求,表单数据附加到URL的问号后面(如上例所示);对于POST请求,表单数据用一个单独的行发送给服务器。

  以前,从这种形式的数据提取出所需要的表单变量是CGI编程中最麻烦的事情之一。首先,GET请求和POST请求的数据提取方法不同:对于GET请求,通常要通过QUERY_STRING环境变量提取数据;对于POST请求,则一般通过标准输入提取数据。第二,程序员必须负责在“&”符号处截断变量名字-变量值对,再分离出变量名字(等号左边)和变量值(等号右边)。第三,必须对变量值进行URL反编码操作。因为发送数据的时候,字母和数字以原来的形式发送,但空格被转换成加号,其他字符被转换成“%XX”形式,其中XX是十六进制表示的字符ASCII(或者ISO Latin-1)编码值。例如,如果HTML表单中名为“users”的域值为“~hall, ~gates, and ~mcnealy”,则实际向服务器发送的数据为“users=%7Ehall%2C+%7Egates%2C+and+%7Emcnealy”。最后,即第四个导致解析表单数据非常困难的原因在于,变量值既可能被省略(如“param1=val1&param2=&param3=val3”),也有可能一个变量拥有一个以上的值,即同一个变量可能出现一次以上(如“param1=val1&param2=val2&param1=val3”)。

  Java Servlet的好处之一就在于所有上述解析操作都能够自动完成。只需要简单地调用一下HttpServletRequest的getParameter 方法、在调用参数中提供表单变量的名字(大小写敏感)即可,而且GET请求和POST请求的处理方法完全相同。

  getParameter方法的返回值是一个字符串,它是参数中指定的变量名字第一次出现所对应的值经反编码得到得字符串(可以直接使用)。如果指定的表单变量存在,但没有值,getParameter返回空字符串;如果指定的表单变量不存在,则返回null。如果表单变量可能对应多个值,可以用 getParameterValues来取代getParameter。getParameterValues能够返回一个字符串数组。

  最后,虽然在实际应用中Servlet很可能只会用到那些已知名字的表单变量,但在调试环境中,获得完整的表单变量名字列表往往是很有用的,利用 getParamerterNames方法可以方便地实现这一点。getParamerterNames返回的是一个Enumeration,其中的每一项都可以转换为调用getParameter的字符串。

  4.2 实例:读取三个表单变量

  下面是一个简单的例子,它读取三个表单变量param1、param2和param3,并以HTML列表的形式列出它们的值。请注意,虽然在发送应答内容之前必须指定应答类型(包括内容类型、状态以及其他HTTP头信息),但Servlet对何时读取请求内容却没有什么要求。

  另外,我们也可以很容易地把Servlet做成既能处理GET请求,也能够处理POST请求,这只需要在doPost方法中调用doGet方法,或者覆盖 service方法(service方法调用doGet、doPost、doHead等方法)。在实际编程中这是一种标准的方法,因为它只需要很少的额外工作,却能够增加客户端编码的灵活性。

  如果你习惯用传统的CGI方法,通过标准输入读取POST数据,那么在Servlet中也有类似的方法,即在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 实例:输出所有的表单数据

  下面这个例子寻找表单所发送的所有变量名字,并把它们放入表格中,没有值或者有多个值的变量都突出显示。

  首先,程序通过HttpServletRequest的getParameterNames方法得到所有的变量名字,getParameterNames 返回的是一个Enumeration。接下来,程序用循环遍历这个Enumeration,通过hasMoreElements确定何时结束循环,利用 nextElement得到Enumeration中的各个项。由于nextElement返回的是一个Object,程序把它转换成字符串后再用这个字符串来调用getParameterValues。

  getParameterValues返回一个字符串数组,如果这个数组只有一个元素且等于空字符串,说明这个表单变量没有值,Servlet以斜体形式输出“No Value”;如果数组元素个数大于1,说明这个表单变量有多个值,Servlet以HTML列表形式输出这些值;其他情况下Servlet直接把变量值放入表格。

  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);

  }

  }

  测试表单

  下面是向上述Servlet发送数据的表单PostForm.html。就像所有包含密码输入域的表单一样,该表单用POST方法发送数据。我们可以看到,在Servlet中同时实现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="$"><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>

责任编辑:

收藏本文 打印 打印本文  推荐本文 告诉好友 投稿 投稿邮箱

站长排行

学院

新闻

专栏

盈利

[揭密网络黄链]中国留学生买凶专破日本
JSP语法(6)
超强弹出窗口代码,什么都挡不住
FLASH视觉特效实例之地震效果
贴吧发帖机使用教程(绝对原创)
关于数据分页(转自www.codeproject.co
ASP实现文件直接下载
Photoshop制作光感超酷效果水晶球
 遍历ASP.NET页面控件
永远的后门[经典]+查不出的后门
淘宝网卖家公然叫卖“艳照门”照片集
驳《百度Hi面世对腾讯有利》
Google绿色专家质疑黑色背景网页节省资
国内各IT企业办公环境揭秘(多图)
阿里妈妈广告卖主全攻略
站长创业源动力 主流站长站赏析
推荐阅读:80年小子的创业道理
Discuz!6.0猛将出击 最强论坛程序酷炫
我的网络,我的团队:专访李文明
百度新闻频道改版十天 流量止跌反弹翻
ECSHOP模板制作参考文档
悬挂阿里妈妈会否被百度惩罚
阿里妈妈是否是中小站长的救世主?
最强网店ECShop发新版 众多酷炫功能给
ECSHOP模板下载
土豆网,优酷网,爆米花等视频网站采集
DedeCms模板安装/制作概述
网上商店系统巅峰对决 ECShop vs ShopE
艰难的走在创业的路上 第一天
编程中国全站采集规则
性福联盟 一个不尊重站长的联盟
大脚:日赚100元—揭露最新firefox欺骗
大脚:垃圾站超级赚钱法之二—突破“站
大脚:垃圾站超级赚钱法之——前言
迅雷联盟、快车联盟收入对比
经理人必看的十个管理网站
Google Adsense的秘密 第二版
西联汇款兑付城市查询
不用SEO取得成功的10个步骤
关于做GOOGLE的五条经验
站长学院  网页设计 建站教程 图形图象 网络编程

Photoshop CS3
Photoshop CS3
不用Photoshop
不用Photoshop

DIV+CSS的开发方式 听听另外的
虚拟主机建站动易里快速生成的
VBScript特效代码 满屏幕乱跑
牛气!一个菜鸟站长的超强网站
创建、维护一个个人博客的“投
让网站流量稳步飙升的秘籍
网站推广的基本思想

新闻线索

如果你有站长界人事变动、重组并购、变革技术出现,以及产品投诉等重要新闻线索,请告诉我们,我们会给予特别关注。
0631-3653338
站长中国编辑部
站长中国24小时新闻热线: 13256307008