客户请求的处理:表单数据

常常会看到这样的URL:http://host/path?user=Marty+Hall&origin=bwi&dest=sfo

它是服务器程序从web页面获取信息的最常见形式----表单数据跟在url后,GET请求即采用这种形式,表单数据也可以在单独的行里发送(POST请求)


topics:

单个请求参数的读取

全部请求参数的读取

缺失和异常数据的处理

过滤请求参数中的特殊字符

用请求参数的值自动填充数据对象

表单提交不完整的应付




1,在servlet中读取表单数据

1)单个值的读取getParameter

request.getParameter("Param1"),不管数据是由GET发送(即在doGET中)还是在doPOST中,都可以这样用。

如果参数存在但没有相应的值返回空的String,如果没有这个参数返回null。


2)多个值的读取getParameterValues,

public String[] getParameterValues(String name);

 通过一个String对象的数组返回指定参数的值,如果这个参数不存在,该方法返回一个空值。返回字符串的数组,同一个参数在表单数据中出现多次,返回字符串的数组。

一般情况下你应避免html表单参数名的重复,(这样就直接用getParameter即可)。但在某些情况下这无可避免,例如在多选列表框中,会为列表框中每个选定的元素重复使用参数名。


3) 参数名的查找getParameterNames 和getParameterMap

public Enumeration getParameterNames();

 返回所有参数名的String对象列表,如果没有输入参数,该方法返回一个空值。

public java.util.Map getParameterMap()
Returns a java.util.Map of the parameters of this request


4)原始表单数据的读取及对上载文件的分析:getReader 或 getInputStream  了解

两种情况下需要读取原始参数:数据不是html表单提交;数据来自于上载的文件


5)多字符集输入的读取:setCharacterEncoding  了解

request.getParameter使用服务器当前的字符集解释输入,要改变这种默认行为,需要使用setCharacterEncoding方法来设置字符集。但是如果输入中使用了多个字符集怎么办,这里提供一种参考的解决方案:

先读取感兴趣的参数,使用getBytes提取原始数据,然后转换为其他的字符集

String firstNameWrongEncoding = request.getParameter("firstName");
String firstName =
new String(firstNameWrongEncoding.getBytes(), "Shift_JIS");

2,示例:读取3个参数

表单:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML><HEAD><TITLE>Collecting Three Parameters</TITLE></HEAD>
<BODY BGCOLOR="#FDF5E6">
<H1 ALIGN="CENTER">Collecting Three Parameters</H1>


<FORM ACTION="/Servlet/servlet/ThreeParams">
  First Parameter:  <INPUT TYPE="TEXT" NAME="param1"><BR>
  Second Parameter: <INPUT TYPE="TEXT" NAME="param2"><BR>
  Third Parameter:  <INPUT TYPE="TEXT" NAME="param3"><BR>

  <CENTER><INPUT TYPE="SUBMIT"></CENTER>
</FORM>

</BODY></HTML>

响应的servlet:

package coreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


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 = "Reading 1111 Three Request Parameters";
    String docType =
      "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
      "Transitional//EN\">\n";
    out.println(docType +
                "<HTML>\n" +
                "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" +
                "<BODY BGCOLOR=\"#FDF5E6\">\n" +
                "<H1 ALIGN=\"CENTER\">" + title + "</H1>\n" +
                "<UL>\n" +
                "  <LI><B>param1</B>: "
                + request.getParameter("param1") + "\n" +//读取参数
                "  <LI><B>param2</B>: "
                + request.getParameter("param2") + "\n" +
                "  <LI><B>param3</B>: "
                + request.getParameter("param3") + "\n" +
                "</UL>\n" +
                "</BODY></HTML>");
  }
}

路径问题:!!!

新建的一个Servlet的web项目:

2011041000001928.png

建好后工程的域名就在http://localhost:8080/Servlet/下   !!!

src下的资源文件,都在web.xml里面可以查到映射的url,填在http://localhost:8080/Servlet/之后即可  !!!

在WebRoot下建的form文件夹下的html文件的路径是:http://localhost:8080/Servlet/form/1.html  !!!

在ACTION里的响应处理文件的servlet路径---工程名+映射的url:ACTION="/Servlet/servlet/ThreeParams"  !!!


3,读取所有参数

获取全部参数:

 
  
Enumeration paramNames = request.getParameterNames();

得到所有参数和参数值:

 
  
1 while (paramNames.hasMoreElements()) {
2 String paramName = (String)paramNames.nextElement();
3
4 String[] paramValues =
5 request.getParameterValues(paramName);

下面是全部的代码:

表单html:

 
  
1 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
2   < HTML >< HEAD >< TITLE > A Sample FORM using POST </ TITLE ></ HEAD >
3   < BODY BGCOLOR ="#FDF5E6" >
4   < H1 ALIGN ="CENTER" > A Sample FORM using POST </ H1 >
5   < FORM ACTION ="/servlet/coreservlets.ShowParameters"
6 METHOD ="POST" >
7 Item Number: < INPUT TYPE ="TEXT" NAME ="itemNum" >< BR >
8 Description: < INPUT TYPE ="TEXT" NAME ="description" >< BR >
9 Price Each: < INPUT TYPE ="TEXT" NAME ="price" VALUE ="$" >< BR >
10 < HR >
11
12 First Name: < INPUT TYPE ="TEXT" NAME ="firstName" >< BR >
13 Last Name: < INPUT TYPE ="TEXT" NAME ="lastName" >< BR >
14 Middle Initial: < INPUT TYPE ="TEXT" NAME ="initial" >< BR >
15 Shipping Address:
16 < TEXTAREA NAME ="address" ROWS =3 COLS =40 ></ TEXTAREA >< BR >
17 Credit Card: < BR >
18 &nbsp;&nbsp; < INPUT TYPE ="RADIO" NAME ="cardType"
19 VALUE ="Visa" > Visa < BR >
20
21 &nbsp;&nbsp; < INPUT TYPE ="RADIO" NAME ="cardType"
22 VALUE ="MasterCard" > MasterCard < BR >
23 &nbsp;&nbsp; < INPUT TYPE ="RADIO" NAME ="cardType"
24 VALUE ="Amex" > American Express < BR >
25 &nbsp;&nbsp; < INPUT TYPE ="RADIO" NAME ="cardType"
26 VALUE ="Discover" > Discover < BR >
27 &nbsp;&nbsp; < INPUT TYPE ="RADIO" NAME ="cardType"
28 VALUE ="Java SmartCard" > Java SmartCard < BR >
29 Credit Card Number:
30 < INPUT TYPE ="PASSWORD" NAME ="cardNum" >< BR >
31 Repeat Credit Card Number:
32 < INPUT TYPE ="PASSWORD" NAME ="cardNum" >< BR >< BR >
33
34 < CENTER >< INPUT TYPE ="SUBMIT" VALUE ="Submit Order" ></ CENTER >
35   </ FORM >
36   </ BODY ></ HTML >

响应servlet:

 
  
1 package coreservlets;
2
3   import java.io. * ;
4   import javax.servlet. * ;
5   import javax.servlet.http. * ;
6   import java.util. * ;
7
8
9
10   public class ShowParameters extends HttpServlet {
11 public void doGet(HttpServletRequest request,
12 HttpServletResponse response)
13 throws ServletException, IOException {
14 response.setContentType( " text/html " );
15 PrintWriter out = response.getWriter();
16 String docType =
17 " <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
18 " Transitional//EN\">\n " ;
19 String title = " Reading All Request Parameters " ;
20 out.println(docType +
21 " <HTML>\n " +
22 " <HEAD><TITLE> " + title + " </TITLE></HEAD>\n " +
23 " <BODY BGCOLOR=\"#FDF5E6\">\n " +
24 " <H1 ALIGN=CENTER> " + title + " </H1>\n " +
25 " <TABLE BORDER=1 ALIGN=CENTER>\n " +
26 " <TR BGCOLOR=\"#FFAD00\">\n " +
27 " <TH>Parameter Name<TH>Parameter Value(s) " );
28 // 关键代码
29   Enumeration paramNames = request.getParameterNames();
30 while (paramNames.hasMoreElements()) {
31 String paramName = (String)paramNames.nextElement();
32 out.print( " <TR><TD> " + paramName + " \n<TD> " );
33 String[] paramValues =
34 request.getParameterValues(paramName);
35 if (paramValues.length == 1 ) {
36 String paramValue = paramValues[ 0 ];
37 if (paramValue.length() == 0 )
38 out.println( " <I>No Value</I> " );
39 else
40 out.println(paramValue);
41 } else {
42 out.println( " <UL> " );
43 for ( int i = 0 ; i < paramValues.length; i ++ ) {
44 out.println( " <LI> " + paramValues[i]);
45 }
46 out.println( " </UL> " );
47 }
48 }
49 out.println( " </TABLE>\n</BODY></HTML> " );
50 }
51
52 public void doPost(HttpServletRequest request,
53 HttpServletResponse response)
54 throws ServletException, IOException {
55 doGet(request, response); // 注意html中是post方法!!!
56   }
57 }

2011041000471089.jpg

提交表单后的结果:

2011041000475978.jpg

4,参数确实或异常时默认值的应用

在用户提交表单时如果有的项没有填写,怎么解决:1)使用默认值。2)提示重新填写

这里解决1.

编写一些函数来处理缺省时的值,比如:

 
  
1 String name = request.getParameter( " name " );
2 name = replaceIfMissing(name, " Lou Zer " );

在得到参数值后,在编写一个如果缺失的情况,使得如果不缺失name保持不变,缺失则替换为一个默认值。。举例略

5,过滤字符串中的html特殊字符

如果servlet希望生成含有<,>等字符的html,就要使用标准的html字符实体来代换这些符号,---

&lt---     <

&gt---    >

&quot---    "

&amp---    &

因为这些符号可能被解释为html属性的结尾。

可以先编写一个过滤的类

 
  
1 package coreservlets;
2
3   import javax.servlet. * ;
4   import javax.servlet.http. * ;
5
6
7
8   public class ServletUtilities {
9 public static final String DOCTYPE =
10 " <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
11 " Transitional//EN\"> " ;
12
13
14 public static String headWithTitle(String title) {
15 return (DOCTYPE + " \n " +
16 " <HTML>\n " +
17 " <HEAD><TITLE> " + title + " </TITLE></HEAD>\n " );
18 }
19
20
21 public static int getIntParameter(HttpServletRequest request,
22 String paramName,
23 int defaultValue) {
24 String paramString = request.getParameter(paramName);
25 int paramValue;
26 try {
27 paramValue = Integer.parseInt(paramString);
28 } catch (NumberFormatException nfe) { // null or bad format
29   paramValue = defaultValue;
30 }
31 return (paramValue);
32 }
33
34 public static double getDoubleParameter
35 (HttpServletRequest request,
36 String paramName,
37 double defaultValue) {
38 String paramString = request.getParameter(paramName);
39 double paramValue;
40 try {
41 paramValue = Double.parseDouble(paramString);
42 } catch (NumberFormatException nfe) { // null or bad format
43   paramValue = defaultValue;
44 }
45 return (paramValue);
46 }
47
48
49   // 将输入中的特殊字符替换后返回的静态方法
50  
51 public static String filter(String input) {
52 if ( ! hasSpecialChars(input)) {
53 return (input);
54 }
55 StringBuffer filtered = new StringBuffer(input.length());
56 char c;
57 for ( int i = 0 ; i < input.length(); i ++ ) {
58 c = input.charAt(i);
59 switch (c) {
60 case ' < ' : filtered.append( " &lt; " ); break ;
61 case ' > ' : filtered.append( " &gt; " ); break ;
62 case ' " ' : filtered.append( " &quot; " ); break ;
63 case ' & ' : filtered.append( " &amp; " ); break ;
64 default : filtered.append(c);
65 }
66 }
67 return (filtered.toString());
68 }
69
70   // 判断是否有特殊字符
71   private static boolean hasSpecialChars(String input) {
72 boolean flag = false ;
73 if ((input != null ) && (input.length() > 0 )) {
74 char c;
75 for ( int i = 0 ; i < input.length(); i ++ ) {
76 c = input.charAt(i);
77 switch (c) {
78 case ' < ' : flag = true ; break ;
79 case ' > ' : flag = true ; break ;
80 case ' " ' : flag = true ; break ;
81 case ' & ' : flag = true ; break ;
82 }
83 }
84 }
85 return (flag);
86 }
87 }

在servlet中可以过滤这个字符串然后输出!!!

6,根据请求参数自动填充java对象:表单bean

由于getParameter返回值是String,所以如果希望得到其他类型的值,转型比较麻烦,在jsp中,使用javabean组件可以极大地简化读取的请求参数。

(jsp页面实质上也是servlet),每个jsp页面都要转换成servlet,在请求运行期间执行的是servlet。在复杂的情况下,一般都是用jsp和servlet组合,servlet完成编程任务而jsp完成表示任务。

jsp提供了javabean,但servlet却并没有实现这种读取参数的方法。不过,apache基金会的Jakarta通用包提供了这样的类,使得我们可以更容易的构建自动请求参数和bean属性关联起来。它的BeanUtilities类下提供了这样的静态方法:

public static void populateBean(Object bean, Map propertyMap)

将map中的所有值传递给bean中与相关的map键名匹配的属性

调用方法:

public static void populateBean(Object formBean,
                                  HttpServletRequest request) {
    populateBean(formBean, request.getParameterMap());
  }

即可完成请求参数到一个bean的自动填充。

 
  
1 package coreservlets.beans;
2
3   import java.util. * ;
4   import javax.servlet.http. * ;
5   import org.apache.commons.beanutils.BeanUtils;
6
7
8   public class BeanUtilities {
9
10
11 public static void populateBean(Object formBean,
12 HttpServletRequest request) {
13   // 从request得到一个map,调用后面的方法来填充
14   populateBean(formBean, request.getParameterMap());
15 }
16
17
18 // map到bean的填充方法
19   public static void populateBean(Object bean,
20 Map propertyMap) {
21 try {
22 BeanUtils.populate(bean, propertyMap);
23 } catch (Exception e) {
24
25 }
26 }
27 }

示例:

表单:

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
2   <!--
3 Front end to InsuranceInfo servlet. Note that the names of
4 the form parameters here *must* match the names of the bean
5 properties.
6
7 Taken from Core Servlets and JavaServer Pages 2nd Edition
8 from Prentice Hall and Sun Microsystems Press,
9 http://www.coreservlets.com/.
10 (C) 2003 Marty Hall; may be freely used or adapted.
11   -->
12   < HTML >< HEAD >< TITLE > Employee Insurance Signup </ TITLE ></ HEAD >
13   < BODY BGCOLOR ="#FDF5E6" >
14   < CENTER >
15   < H1 > Employee Insurance Signup </ H1 >
16
17   < FORM ACTION ="/servlet/coreservlets.SubmitInsuranceInfo" >
18 Name: < INPUT TYPE ="TEXT" NAME ="name" >< BR >
19 Employee ID: < INPUT TYPE ="TEXT" NAME ="employeeID" >< BR >
20 Number of Children: < INPUT TYPE ="TEXT" NAME ="numChildren" >< BR >
21
22 < INPUT TYPE ="CHECKBOX" NAME ="married" VALUE ="true" > Married? < BR >
23 < CENTER >< INPUT TYPE ="SUBMIT" ></ CENTER >
24   </ FORM >
25
26   </ CENTER ></ BODY ></ HTML >

bean:

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 package coreservlets.beans;
2
3   import coreservlets. * ;
4
5
6   public class InsuranceInfo {
7 private String name = " No name specified " ;
8 private String employeeID = " No ID specified " ;
9 private int numChildren = 0 ;
10 private boolean isMarried = false ;
11
12 public String getName() {
13 return (name);
14 }
15 public void setName(String name) {
16 this .name = ServletUtilities.filter(name);
17 }
18
19
20 public String getEmployeeID() {
21 return (employeeID);
22 }
23 public void setEmployeeID(String employeeID) {
24 this .employeeID = ServletUtilities.filter(employeeID);
25 }
26
27
28 public int getNumChildren() {
29 return (numChildren);
30 }
31 public void setNumChildren( int numChildren) {
32 this .numChildren = numChildren;
33 }
34
35
36 public boolean isMarried() {
37 return (isMarried);
38 }
39
40 public void setMarried( boolean isMarried) {
41 this .isMarried = isMarried;
42 }
43 }

servlet:

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 package coreservlets;
2
3   import java.io. * ;
4   import javax.servlet. * ;
5   import javax.servlet.http. * ;
6   import coreservlets.beans. * ;
7
8
9   public class SubmitInsuranceInfo extends HttpServlet {
10 public void doGet(HttpServletRequest request,
11 HttpServletResponse response)
12 throws ServletException, IOException {
13
14   // 一步完成所有参数的填充,info是一个 bean对象
15   InsuranceInfo info = new InsuranceInfo();
16 BeanUtilities.populateBean(info, request);
17
18 response.setContentType( " text/html " );
19 PrintWriter out = response.getWriter();
20 String docType =
21 " <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
22 " Transitional//EN\">\n " ;
23 String title = " Insurance Info for " + info.getName();
24 out.println(docType +
25 " <HTML>\n " +
26 " <HEAD><TITLE> " + title + " </TITLE></HEAD>\n " +
27 " <BODY BGCOLOR=\"#FDF5E6\">\n " +
28 " <CENTER>\n " +
29 " <H1> " + title + " </H1>\n " +
30 " <UL>\n " +
31 " <LI>Employee ID: " +
32 info.getEmployeeID() + " \n " + // 从bean对象里取值
33   " <LI>Number of children: " +
34 info.getNumChildren() + " \n " +
35 " <LI>Married?: " +
36 info.isMarried() + " \n " +
37 " </UL></CENTER></BODY></HTML> " );
38 }
39 }

7,参数缺失或异常时重新显示输入表单

当用户没有填写某些表单时,有时候需要使用默认值(如上述4中讲述),但有时候没有合适的默认值,这时需要

1)用户不应该再次输入已经提供的值

2)缺失的表单域应该突出的表示出来 提醒用户有未填写的项

一种解决方案:

判断bean对象(即表单的form)是否完全为空等情况,根据不同的情况,调用不同的方法去显示---

 
  
1 public void doGet(HttpServletRequest request,
2 HttpServletResponse response)
3 throws ServletException, IOException {
4
5 BidInfo bid = new BidInfo(); // 表单bean对象
6   BeanUtilities.populateBean(bid, request); // 通过bean赋值
7
8   // 判断bean填充完整性的情形,调用不同的方法去处理
9   if (bid.isComplete()) {
10 showBid(request, response, bid);
11 } else {
12 showEntryForm(request, response, bid);
13 }
14 }

转载于:https://www.cnblogs.com/jmzz/archive/2011/04/09/2010456.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值