1客户请求的处理:表单数据2•表单数据的功用•HTML表单的创建和提交•单个请求参数的读取•整个系列请求参数的读取•数据缺失或者异常时的处理•不完整表单提交的应对•请求参数中特殊字符的过滤3表单数据的功用•在线旅行社可能会用到的URL–=Wang+Wu&origin=HZ&dest=BJ–名称由HTML制作者指定,而值由昀终用户提供。•传统CGI中对表单(查询)数据的解析–采用不同的方式读取GET请求(QUERY_STRING)和POST请求(标准输入)的数据。–在&符号处将名/值对拆分开来,然后将参数名(等号左边)和参数值(等号右边)分开。–对值进行URL解码(比如,“%7E”变为~“)•在servlet中这一切得到极大简化–所有情况下都使用request.getParameter。–直接给出经过URL解码后的结果4表单数据的创建:HTML窗体!DOCTYPEHTMLPUBLIC-//W3C//DTDHTML4.0Transitional//ENHTMLHEADTITLEASampleFormUsingGET/TITLE/HEADBODYBGCOLOR=#FDF5E6H2ALIGN=CENTERASampleFormUsingGET/H2FORMACTION=:INPUTTYPE=TEXTNAME=firstNameVALUE=JoeBRLastname:INPUTTYPE=TEXTNAME=lastNameVALUE=HackerPINPUTTYPE=SUBMIT!--Pressthistosubmitform--/CENTER/FORM/BODY/HTML5HTML表单:初始结果6HTML表单:提交的结果(发送到EchoServer的数据)7POST数据的发送!DOCTYPEHTMLPUBLIC-//W3C//DTDHTML4.0Transitional//ENHTMLHEADTITLEASampleFormUsingPOST/TITLE/HEADBODYBGCOLOR=#FDF5E6H2ALIGN=CENTERASampleFormUsingPOST/H2FORMACTION==POSTCENTERFirstname:INPUTTYPE=TEXTNAME=firstNameVALUE=JoeBRLastname:INPUTTYPE=TEXTNAME=lastNameVALUE=HackerPINPUTTYPE=SUBMIT/CENTER/FORM/BODY/HTML8POST数据的发送9servlet中表单数据的读取•request.getParameter(name)–返回查询字符串中name首次出现时所对应的值,已经完成URL解码–无论GET和POST请求都以相同的方式工作–如果在查询数据中没有这个参数,则返回null•request.getParameterValues(name)–返回查询字符中name所对应的所有值构成的数组,已完成URL解码–如果参数没有重复出现,则返回仅有一个元素的数组–如果在查询中没有这个参数则返回null•request.getParameterNames()或request.getParameterMap()–返回请求参数构成的Enumeration或Map–常常仅用于调试目的10原始表单数据的读取以及对上载文件的分析•原始数据–request.getReader–request.getInputStream•这样做之后,就不能再通过getParameter来获取数据•上载文件的分析–HTML拥有提交整个文件的方法•INPUTTYPE=FILE…–servlet/JSPAPI没有内建的方式可以对这类文件进行分析–Apache/Jakarta的“Commons”库中提供流行的第三方库提供这类支持•含有三个参数的HTML表单FORMACTION=/servlet/coreservlets.ThreeParamsFirstParameter:INPUTTYPE=TEXTNAME=param1BRSecondParameter:INPUTTYPE=TEXTNAME=param2BRThirdParameter:INPUTTYPE=TEXTNAME=param3BRCENTERINPUTTYPE=SUBMIT/CENTER/FORM12读取三个参数publicclassThreeParamsextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{…out.println(docType+HTML\n+HEADTITLE+title+/TITLE/HEAD\n+BODYBGCOLOR=\#FDF5E6\\n+H1ALIGN=\CENTER\+title+/H1\n+UL\n+LIBparam1/B:+request.getParameter(param1)+\n+LIBparam2/B:+request.getParameter(param2)+\n+LIBparam3/B:+request.getParameter(param3)+\n+/UL\n+/BODY/HTML);}}13读取三个参数处理后的结果14读取所有参数publicclassShowParametersextendsHttpServlet{publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{response.setContentType(text/html);PrintWriterout=response.getWriter();StringdocType=!DOCTYPEHTMLPUBLIC\-//W3C//DTDHTML4.0+Transitional//EN\\n;Stringtitle=ReadingAllRequestParameters;out.println(docType+HTML\n+HEADTITLE+title+/TITLE/HEAD\n+BODYBGCOLOR=\#FDF5E6\\n+H1ALIGN=CENTER+title+/H1\n+TABLEBORDER=1ALIGN=CENTER\n+TRBGCOLOR=\#FFAD00\\n+THParameterNameTHParameterValue(s));15读取所有参数(续)EnumerationparamNames=request.getParameterNames();while(paramNames.hasMoreElements()){StringparamName=(String)paramNames.nextElement();out.print(TRTD+paramName+\nTD);String[]paramValues=request.getParameterValues(paramName);if(paramValues.length==1){StringparamValue=paramValues[0];if(paramValue.length()==0)out.println(INoValue/I);elseout.println(paramValue);}else{out.println(UL);for(inti=0;iparamValues.length;i++){out.println(LI+paramValues[i]);}out.println(/UL);}}out.println(/TABLE\n/BODY/HTML);}16读取所有参数(续)publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{doGet(request,response);}}17读取所有参数(简单表单)18读取所有参数(结果)19数据缺失或异常的检查•缺失–表单中缺失某个字段•getParameter返回null–表单提交时字段为空•getParameter返回空字符串(或者由空格组成的字符串)–在检查字符串是否为空之前必须检查它是否为nullStringparam=request.getParameter(someName);if((param==null)||(param.trim().equals())){doSomethingForMissingValues(...);}else{doSomethingWithParameter(param);}•异常–值为非空字符串,但格式错误20缺失或异常数据的处理•使用默认值–用应用程序特定的标准值来替代缺失的值–参见随后的例子•再次显示表单–再次显示表单,将缺失的值标示出来–之前已经输入的值应该保留–实现这个功能有四种选择:•由同一个servlet呈现表单、处理数据、并呈现结果。•由一个servlet呈现表单;由另一个servlet处理数据并呈现结果。•由JSP页面“手动地”呈现表单;由servlet或JSP页面处理数据并呈现结果。•由JSP页面呈现表单,自动用从数据对象获得的值填充各个字段。由servlet或JSP页面处理数据并呈现结果。–具体的例子请参考本书的内容21应用默认值的例子:简历张贴网站22简历张贴网站:输入表单23简历张贴网站:servlet代码headingFont=replaceIfMissingOrDefault(headingFont,);intheadingSize=getSize(request.getParameter(headingSize),32);StringbodyFont=request.getParameter(bodyFont);bodyFont=replaceIfMissingOrDefault(bodyFont,);intbodySize=getSize(request.getParameter(bodySize),18);StringfgColor=request.getParameter(fgColor);fgColor=replaceIfMissing(fgColor,BLACK);StringbgColor=request.getParameter(bgColor);24简历张贴网站:servlet代码(续)privateStringreplaceIfMissing(Stringorig,Stringreplacement){if((orig==null)||(orig.trim().equals())){return(replacement);}else{return(orig);}}25简历张贴网站:不完整数据所获得的结果26