第15章 JSP表单处理返回主页上一章下一章在JSP编程中,为了实现用户和网站之间的信息交互,通常都要在网页上设计表单,然后使用特定方法收集表单数据信息并进行处理。本章重点介绍利用JSP的Request对象的getParameter方法来获取表单数据的方法。当然,数据库连接对动态网站来说是非常重要的,对此本章将详细介绍JSP的数据库连接技术JDBC-ODBC bridge。为了防止JSP 访问数据库中的中文信息时可能出现的乱码问题,可以采用将字符串由8859_1(或iso-8859-1)码转换成gb2312码的方法来有效解决。15.1 表单信息的获取
15.2 与数据库结合的表单处理
15.3 中文乱码问题
☆进入DOS状态☆写字版☆绘图板☆进入Editplus
15.1 表单信息的获取本章开头下一节
大家应该对表单很熟悉,随便进入一个网站,如果想在线注册成为某网站的会员,就必须填写一张表单,然后提交给服务器处理。例如图15-1显示的是QQ聊天网站的会员注册表单。
图15-1 QQ会员注册表单示意图
表单在HTML页面中起着非常重要作用,它是实现与用户信息交互的重要手段。一个表单至少应该包括说明性文字、用户填写的表格、提交和重填按钮等内容。用户填写了所需的资料之后,按下“提交资料”按钮,所填资料就会通过一个专门的接口传到Web服务器上。经服务器处理后反馈给用户结果,从而完成用户和网络之间的交流。
一般情况下,表单设计时使用的标记包括:
1.
其基本语法结构如下:
onreset=function1 onsubmit=function2 >
action属性:用于指定处理表单数据程序的url地址。采用电子邮件方式时,用action="mailto:目标邮件地址"。
method属性:指定数据传送到服务器的方式。当method=get(默认值)时,将输入数据加在action指定的地址后面传送到服务器;当method=post时,则将输入数据按照HTTP传输协议中的post传输方式传送到服务器,用电子邮件接收用户信息也采用这种方式。
name属性:用于设定表单的名称。
onreset属性(onsubmit属性)设定了在按下reset按钮(submit 按钮)之后要执行的子程序。
2.表单输入标记
type=text|textarea|password|checkbox|radio|
submit|reset|file|hidden|image|button value=the_value src=url checked maxlength=n size=n onclick=function onselect=function>属性name设定当前变量名称。
属性type的值决定了输入数据的类型。其选项较多,各项的意义如下:
type=text:表示输入单行文本。
typet=textarea:表示输入多行文本。
type=password:表示输入数据为密码,用星号表示。
type=checkbox:表示复选框。
type=radio:表示单选框。
type=submit:表示提交按钮,数据将被送到服务器。
type=reset:表示清除表单数据,以便重新输入。
type=file:表示插入一个文件。
type=hidden:表示隐藏按钮。
type=image:表示插入一个图像。
type=button:表示普通按钮。
value=the_value:用于设定输入默认值the_value,即如果用户不输入的话,就采用此默认值。
src=filename:是针对type=image的情况来说的,指定图像文件。
属性checked:在type取值radio/checkbox时有效,表示该项被默认选中。
属性maxlength:在type取值text时有效,表示最大输入字符的个数。
属性size:在type取值texyarea时有效,表示在输入多行文本时的最大输入字符个数。
属性onclick:表示在按下输入时调用指定的子程序。
属性onselect:表示当前项被选择时调用指定的子程序。
3.下拉菜单标记
用标记用于在表单中插入一个下拉菜单,它需与标记配合使用,其基本语法结构如下:
…
属性name:设定下拉式菜单的名称。
属性size:设定一次显示菜单项的个数,默认值=1;
属性multiple:表示可以进行多选;
标记:表示下拉菜单中一个选项;
属性selected表示该选项默认选中;
属性value表示该选项对应的值,在该选项被中之后,其值就会被送到服务器进行处理。
4.多行文本输入标记
cols=n rows=n wrap=off|hard|soft>
属性name:表示文本框名称;
属性clos、rows:分别表示多行文本输入框的宽度和高度(列数、行数);
属性wrap:进行换行控制,当wrap=off时不自动换行;当wrap =hard时自动硬回车换行,换行标记一同被传送到服务器中去;当wrap =soft时自动软回车换行,换行标记不会传送到服务器中去。
例15-1下列exa15_1.html文件用来说明一些常用标记的应用,运行结果见图15-2。
<%@ page contentType="text/html;charset=gb2312"%>
用户注册
您的尊姓大名:
size="15"> 您的密码:
name="pwd" size="16">
你最喜欢的运动:
足
球
排球
您的性别:
男
女
请填写您的计算机配置:
CPU PIV 2700
Memory 256M DDR
您的计算机操作系统图标
您的家庭所在地:
福州 厦门
泉州
三明
图15-2 exa15_1.html运行结果
在讲述如何获取表单信息之前,先介绍一些用JavaScript编写的函数。这些函数用于检验表单中所要提交的数据格式是否正确,只有当数据格式符合要求才允许提交。可以将这些函数存放到一个文件中(比如Jspconfirm.js),然后将此文件包含到所编写的网页中,当然也可以根据需要在网页中单独引用。
(1)isDate()日期确认函数
功能:确认所输入的数据是否是一个有效的日期(格式为:月/日/年),如果是函数返回true,否则返回false。
function isDate (myStr)
{ var the1st=myStr.indexof(‘/’);
var the2nd=https://www.wendangku.net/doc/eb5910376.html,stIndexof(‘/’);
if (the1st==the2nd) { return(false); }
else { var m=myStr.substring(0,the1st);
var d= myStr.substring(the1st+1,the2nd);
var y= myStr.substring(the2nd+1, myStr.length);
var maxDays=31;
if (isInt(m)==false || isInt(d)==false ||
isInt(y)==false)
{ return(false);}
else if (y.length<4){return(false);}
else if (!isBetween(m,1,12)){return(false);}
else if (m==4 || m==6 || m==9 || m==11) maxDays=30;
else if (m==2){if (y%4 >0) maxDays=28; else maxDays=29;}
if (isBetween(d,1,maxDays)==false){return(false);} else {return(true);}
}
(2)isBetween(val,low,high)范围确定函数
功能:确认所输入的数据是否位于参数low和high之间,如果是函数返回true,否则返回false。
function isBetween(val,low,high)
{ if ((valhigh) { return(false); }
else {return(true);}
(3)isTime()时间确认函数
功能:确认所输入的数据是否是一个合法的时间值(格式:HH:MM)。如果是函数返回true,否则返回false。
function isTime (timeStr)
{ var colondex=myStr.indexof(‘:’);
if (colonDex<1)||(colonDex>2)) { return(false); }
else { var hh=timeStr.substring(0, colonDex);
var ss= timeStr.substring(colonDex+1,
timeStr.length);
if ((hh.length<1)||(hh.length>2)||
(!isInt(hh))) {return(false);}
else if
((ss.length<1)||(ss.length>2)(!isInt(ss))){return(fals
e);}
else if ((!isBetween (hh,0,23))|| (!isBetween
(ss,0,59))){return(false);}
(4)isDigit(myNum)数字确认函数
功能:确认所输入的数据是否是一个合法数字。如果是函数返回true,否则返回false。
function isDigit(myNum)
{ var mask= ’ 0123456789’;
if (isEmpty(myNum)) { return(false); }
else if (mask.indexOf(myNum)==-1) {return(false);}
return(true); }
(5)isEmail(myStr)电子邮件确认函数
功能:确认所输入的数据是否是一个合法的电子邮件地址。如果是函数返回true,否则返回false。
function isEmail(myStr)
{ var atIndex=myStr.indexOf(‘@’);
var dotIndex= myStr.indexOf(‘.’,atIndex);
var flag=true;
theSub=myStr.substring(0,dotIndex+1);
if ((atIndex<1)||
(atIndex!=https://www.wendangku.net/doc/eb5910376.html,stInd exOf(‘@’))||
(dotIndex(myStr.length<=theSub.length)){ flag=false}; }else {flag=true;}return(flag);}(6)isEmpty(myStr)功能:确认所输入的数据是否为空。如果为空函数返回true,否则返回false。function isEmpty(myStr){ if ((myStr==null)|| (myStr.length==0))return(true);else return(false); }(7)isInt(myStr)功能:确认所输入的数据是否是一个合法的整数。如果是函数返回true,否则返回false。function isInt(myStr){ var flag= true;if (isEmpty(myStr)) { flag=false}; }else {for (var i=0;i{ if (isDigit(myStr.substring(i,i+1))==false){ flag=false; break;}}}return(flag);}(8)isReal(myStr,decLen)功能:确认所输入的数据是否是一个合法的实数。如果是函数返回true,否则返回false。function isReal(myStr,decLen){ var dot1st= myStr.indexOf(‘.’);var dot2nd= https://www.wendangku.net/doc/eb5910376.html,stIndexOf(‘.’);var flag= true;if (isEmpty(myStr)) return(false);if (dot1st=-1){ if (!isInt(myStr)) return(false);else return(true); }else if (dot1st!=dot2nd)return (false);else if (dot1st==0)return (false);else {var intPart=myStr.substring(0,dot1st);var decPart= myStr.substring(dot2nd+1);if (decPart.length>decLen)return(false);else if (!isInt(intPart)||!isInt(decPart))return(false);else if (isEmpty(decPart))return (false);else return(true);}}例15-2 如何提取客户端表单中的数据,文件名为exa15_2.html,运行结果如图15-3所示,其源码如下:用户注册网页
(myStr.length<=theSub.length)){ flag=false}; }
else {flag=true;}
return(flag);
(6)isEmpty(myStr)
功能:确认所输入的数据是否为空。如果为空函数返回true,否则返回false。
function isEmpty(myStr)
{ if ((myStr==null)|| (myStr.length==0))
return(true);
else return(false); }
(7)isInt(myStr)
功能:确认所输入的数据是否是一个合法的整数。如果是函数返回true,否则返回false。
function isInt(myStr)
{ var flag= true;
if (isEmpty(myStr)) { flag=false}; }
else {for (var i=0;i{ if (isDigit(myStr.substring(i,i+1))==false){ flag=false; break;}}}return(flag);}(8)isReal(myStr,decLen)功能:确认所输入的数据是否是一个合法的实数。如果是函数返回true,否则返回false。function isReal(myStr,decLen){ var dot1st= myStr.indexOf(‘.’);var dot2nd= https://www.wendangku.net/doc/eb5910376.html,stIndexOf(‘.’);var flag= true;if (isEmpty(myStr)) return(false);if (dot1st=-1){ if (!isInt(myStr)) return(false);else return(true); }else if (dot1st!=dot2nd)return (false);else if (dot1st==0)return (false);else {var intPart=myStr.substring(0,dot1st);var decPart= myStr.substring(dot2nd+1);if (decPart.length>decLen)return(false);else if (!isInt(intPart)||!isInt(decPart))return(false);else if (isEmpty(decPart))return (false);else return(true);}}例15-2 如何提取客户端表单中的数据,文件名为exa15_2.html,运行结果如图15-3所示,其源码如下:用户注册网页
{ if (isDigit(myStr.substring(i,i+1))==false)
{ flag=false; break;}
(8)isReal(myStr,decLen)
功能:确认所输入的数据是否是一个合法的实数。如果是函数返回true,否则返回false。
function isReal(myStr,decLen)
{ var dot1st= myStr.indexOf(‘.’);
var dot2nd= https://www.wendangku.net/doc/eb5910376.html,stIndexOf(‘.’);
var flag= true;
if (isEmpty(myStr)) return(false);
if (dot1st=-1)
{ if (!isInt(myStr)) return(false);
else return(true); }
else if (dot1st!=dot2nd)return (false);
else if (dot1st==0)return (false);
else {
var intPart=myStr.substring(0,dot1st);
var decPart= myStr.substring(dot2nd+1);
if (decPart.length>decLen)return(false);
else if (!isInt(intPart)||!isInt(decPart))return
(false);
else if (isEmpty(decPart))return (false);
else return(true);
例15-2 如何提取客户端表单中的数据,文件名为exa15_2.html,运行结果如图15-3所示,其源码如下:
您的用户名:
size="20">
请给定密码:
您最喜欢的颜色:
红色 黄色 蓝色 白色 黑色
图15-3 exa15_2.jsp运行结果
其中表单信息提取程序formget.jsp的源代码如下:<%@ page contentType="text/html; charset=gb2312" %>
<%request.setCharacterEncoding("gb2312");String username=request.getParameter("user");String pwdinfo=request.getParameter("pwd");String sexinfo=request.getParameter("sex");String colorinfo=request.getParameter("likecolor");out.println("您的姓名:");out.println(username);out.println("您的密码:");out.println(pwdinfo);if(sexinfo==null)out.println("很抱歉,您没有选择性别!");else{ out.println("您的性别:");out.println(sexinfo);}if(colorinfo==null)out.println("很抱歉,您没有选择您喜欢的颜色!");else{ out.println("您喜欢的颜色:");out.println(colorinfo);}%>当输入完整的个人信息时,结果显示如图15-4所示,当输入信息不完整时(例如没有输入喜欢的颜色或者没有选择性别),结果显示如图15-5所示。图15-4 输入完整信息提交后的exa15_2.jsp运行结果图15-5 输入不完整信息提交后的exa15_2.jsp运行结果从这个程序中不难发现JSP主要是通过request.getParameter()方法来提取表单中的数据,但需要注意的是,在编写表单时,对于表单中任一元素的name必须赋值,因为JSP调用request对象的方法getParameter()时,正是将name值作为该方法的形参来提取表单中相应元素中的输入数据。除此之外,还可以通过JavaBean技术来获取表单中的信息。当然在这个Bean对应的类体中必须定义一个区域,并且该区域跟表单中的每一个区域相对应。有关Bean的使用详见本书第18章。15.2 与数据库结合的表单处理上一节下一节本章开头在进行表单处理时经常会遇到表单的确认问题,这时需要验证表单中大量的数据。数据格式的合法性一般应该在客户端验证,除非想要对检验的算法进行保密。数据内容(如用户名、密码等)的检查一般不能放在客户端进行,必须通过访问数据库才能来完成表单数据验证的过程。为实现这一环节,就需要JSP与数据库的连接。在JSP中访问数据库,有多种方法,详见本书第16章。本节采用通过JDBC-ODBC桥操作数据源的方法,这对于各种数据库都适用。现在要做的就是在JSP页面中嵌入JDBC-ODBC桥,经过JDBC-ODBC桥的映射,使JSP可以访问数据库。具体做法是在JSP中嵌入如下语句:try { Connection con = DriverManager.getConnection ("jdbc:odbc:数据源的名字","loginname", "password");catch (SQLException e) {}注意:其中参数loginname是登录数据源的用户名字,参数password 是登录口令。如果在设置数据源的过程中没有设置这两项,那么在getConnection方法中也不能省略它们,参数写成”” 的形式。如果连接数据源不成功,系统将抛出一个SQLExpection异常。
<%
request.setCharacterEncoding("gb2312");
String username=request.getParameter("user");
String pwdinfo=request.getParameter("pwd");
String sexinfo=request.getParameter("sex");
String colorinfo=request.getParameter("likecolor");
out.println("您的姓名:");
out.println(username);
out.println("您的密码:");
out.println(pwdinfo);
if(sexinfo==null)out.println("很抱歉,您没有选择性别!
");
else
{ out.println("您的性别:");
out.println(sexinfo);
if(colorinfo==null)out.println("很抱歉,您没有选择您喜
欢的颜色!");
{ out.println("您喜欢的颜色:");
out.println(colorinfo);
}%>
当输入完整的个人信息时,结果显示如图15-4所示,当输入信息不完整时(例如没有输入喜欢的颜色或者没有选择性别),结果显示如图15-5所示。
图15-4 输入完整信息提交后的exa15_2.jsp运行结果
图15-5 输入不完整信息提交后的exa15_2.jsp运行结果从这个程序中不难发现JSP主要是通过request.getParameter()方法来提取表单中的数据,但需要注意的是,在编写表单时,对于表单中任一元素的name必须赋值,因为JSP调用request对象的方法getParameter()时,正是将name值作为该方法的形参来提取表单中相应元素中的输入数据。除此之外,还可以通过JavaBean技术来获取表单中的信息。当然在这个Bean对应的类体中必须定义一个区域,并且该区域跟表单中的每一个区域相对应。有关Bean的使用详见本书第18章。
15.2 与数据库结合的表单处理上一节下一节本章开头
在进行表单处理时经常会遇到表单的确认问题,这时需要验证表单中大量的数据。数据格式的合法性一般应该在客户端验证,除非想要对检验的算法进行保密。数据内容(如用户名、密码等)的检查一般不能放在客户端进行,必须通过访问数据库才能来完成表单数据验证的过程。为实现这一环节,就需要JSP与数据库的连接。
在JSP中访问数据库,有多种方法,详见本书第16章。本节采用通过JDBC-ODBC桥操作数据源的方法,这对于各种数据库都适用。现在要做的就是在JSP页面中嵌入JDBC-ODBC桥,经过JDBC-ODBC桥的映射,使JSP可以访问数据库。具体做法是在JSP中嵌入如下语句:try { Connection con = DriverManager.getConnection ("jdbc:odbc:数据源的名字","loginname", "password");
catch (SQLException e) {}
注意:其中参数loginname是登录数据源的用户名字,参数password 是登录口令。如果在设置数据源的过程中没有设置这两项,那么在getConnection方法中也不能省略它们,参数写成”” 的形式。如果连接数据源不成功,系统将抛出一个SQLExpection异常。