|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
ruby里有这些工具吗?又要简单多少?我没有用过这两门语言,我估计在这些语言力没有很统一的这种标准,或者根本就没有提供。
在很多使用程序中利用GET都没有成绩。可是,GET请求经由过程一个情况变量将本人的数据传送给CGI程序。但假设GET字串太长,有些Web服务器大概用光本人的情况空间(若字串长度凌驾200字符,就应入手下手体贴这方面的成绩)。CGI为此供应了一个办理计划:POST。经由过程POST,数据能够编码,并按与GET不异的办法保持起来。但POST使用尺度输出将编码事后的查询字串传送给CGI程序。我们要做的全体事变就是判别查询字串的长度,而这个长度已在情况变量CONTENT_LENGTH中保留好了。一旦晓得了长度,便可自在分派存储空间,并从尺度输出中读进指定命量的字符。
对一个用来把持POST的CGI程序,由CGITools.h供应的Pair和CGI_vector都可不加涓滴改动地利用。上面这段程序展现了写如许的一个CGI程序有何等复杂。这个例子将接纳“纯”C++,以是studio.h库被iostream(IO数据流)取代。关于iostream,我们可使用两个事后界说好的对象:cin,用于同尺度输出毗连;和cout,用于同尺度输入毗连。有几个举措可从cin中读进数据和向cout中写进。但上面这个程序筹办接纳尺度办法:用“<<”将信息发给cout,并用一个成员函数(此时是read())从cin中读进数据:
- //:POSTtest.cpp
- //CGI_vectorworksaseasilywithPOSTasit
- //doeswithGET.Writtenin"pure"C++.
- #include<iostream.h>
- #include"CGITools.h"
- voidmain(){
- cout<<"Content-type:text/plain
- "<<endl;
- //ForaCGI"POST,"theserverputsthelength
- //ofthecontentstringintheenvironment
- //variableCONTENT_LENGTH:
- char*clen=getenv("CONTENT_LENGTH");
- if(clen==0){
- cout<<"ZeroCONTENT_LENGTH"<<endl;
- return;
- }
- intlen=atoi(clen);
- char*query_str=newchar[len+1];
- cin.read(query_str,len);
- query_str[len]=\0;
- CGI_vectorquery(query_str);
- //Test:dumpallnamesandvalues
- for(inti=0;i<query.size();i++)
- cout<<"query["<<i<<"].name()=["<<
- query[i].name()<<"],"<<
- "query["<<i<<"].value()=["<<
- query[i].value()<<"]"<<endl;
- deletequery_str;//Releasestorage
- }///:~
复制代码
getenv()函数前往指向一个字串的指针,谁人字串唆使着内容的长度。若指针为零,标明CONTENT_LENGTH情况变量还没有设置,以是一定某个中央出了成绩。不然就必需用ANSIC库函数atoi()将字串转换成一个整数。这个长度将与new一同使用,分派充足的存储空间,以便包容查询字串(另加它的空中断符)。随后为cin()挪用read()。read()函数必要获得指向方针缓冲区的一个指针和要读进的字节数。随后用空字符(null)中断query_str,指出已到达字串的开端,这就叫作“空中断”。
到这个时分,我们失掉的查询字串与GET查询字串已没有甚么区分,以是把它传送给用于CGI_vector的构建器。随后便和前例一样,我们能够自在vector内分歧的字段。
为测试这个程序,必需把它编译到主机Web服务器的cgi-bin目次下。然后就能够写一个复杂的HTML页举行测试,就象上面如许:
- <HTML>
- <HEAD>
- <METACONTENT="text/html">
- <TITLE>AtestofstandardHTMLPOST</TITLE>
- </HEAD>
- Test,usesstandardhtmlPOST
- <Formmethod="POST"ACTION="/cgi-bin/POSTtest">
- <P>Field1:<INPUTTYPE="text"NAME="Field1"
- VALUE=""size="40"></p>
- <P>Field2:<INPUTTYPE="text"NAME="Field2"
- VALUE=""size="40"></p>
- <P>Field3:<INPUTTYPE="text"NAME="Field3"
- VALUE=""size="40"></p>
- <P>Field4:<INPUTTYPE="text"NAME="Field4"
- VALUE=""size="40"></p>
- <P>Field5:<INPUTTYPE="text"NAME="Field5"
- VALUE=""size="40"></p>
- <P>Field6:<INPUTTYPE="text"NAME="Field6"
- VALUE=""size="40"></p>
- <p><inputtype="submit"name="submit"></p>
- </Form>
- </HTML>
复制代码
填好这个表单并提交进来今后,会失掉一个复杂的文本页,个中包括懂得析出来的了局。从中可晓得CGI程序是不是在一般事情。
固然,用一个程序片来提交数据显得更风趣一些。但是,POST数据的提交属于一个分歧的历程。在用惯例体例挪用了CGI程序今后,必需另行创建与服务器的一个毗连,以便将查询字串反应给它。服务器随后会举行一番处置,再经由过程尺度输出将查询字串反应回CGI程序。
为创建与服务器的一个间接毗连,必需获得本人创立的URL,然后挪用openConnection()创立一个URLConnection。可是,因为URLConnection一样平常不同意我们把数据发给它,以是必需很好笑地挪用setDoOutput(true)函数,同时挪用的还包含setDoInput(true)和setAllowUserInteraction(false)——正文⑥。最初,可挪用getOutputStream()来创立一个OutputStream(输入数据流),并把它封装到一个DataOutputStream里,以便能按传统体例同它通讯。上面列出的即是一个用于完成上述事情的程序片,必需在从它的各个字段里搜集了数据以后再实行它:
- //:POSTtest.java
- //AnappletthatsendsitsdataviaaCGIPOST
- importjava.awt.*;
- importjava.applet.*;
- importjava.net.*;
- importjava.io.*;
- publicclassPOSTtestextendsApplet{
- finalstaticintSIZE=10;
- Buttonsubmit=newButton("Submit");
- TextField[]t=newTextField[SIZE];
- Stringquery="";
- Labell=newLabel();
- TextAreata=newTextArea(15,60);
- publicvoidinit(){
- Panelp=newPanel();
- p.setLayout(newGridLayout(t.length+2,2));
- for(inti=0;i<t.length;i++){
- p.add(newLabel(
- "Field"+i+"",Label.RIGHT));
- p.add(t[i]=newTextField(30));
- }
- p.add(l);
- p.add(submit);
- add("North",p);
- add("South",ta);
- }
- publicbooleanaction(Eventevt,Objectarg){
- if(evt.target.equals(submit)){
- query="";
- ta.setText("");
- //Encodethequeryfromthefielddata:
- for(inti=0;i<t.length;i++)
- query+="Field"+i+"="+
- URLEncoder.encode(
- t[i].getText().trim())+
- "&";
- query+="submit=Submit";
- //SendthenameusingCGIsPOSTprocess:
- try{
- URLu=newURL(
- getDocumentBase(),"cgi-bin/POSTtest");
- URLConnectionurlc=u.openConnection();
- urlc.setDoOutput(true);
- urlc.setDoInput(true);
- urlc.setAllowUserInteraction(false);
- DataOutputStreamserver=
- newDataOutputStream(
- urlc.getOutputStream());
- //Sendthedata
- server.writeBytes(query);
- server.close();
- //Readanddisplaytheresponse.You
- //cannotuse
- //getAppletContext().showDocument(u);
- //todisplaytheresultsasaWebpage!
- DataInputStreamin=
- newDataInputStream(
- urlc.getInputStream());
- Strings;
- while((s=in.readLine())!=null){
- ta.appendText(s+"
- ");
- }
- in.close();
- }
- catch(Exceptione){
- l.setText(e.toString());
- }
- }
- elsereturnsuper.action(evt,arg);
- returntrue;
- }
- }///:~
复制代码
⑥:我不能不说本人并没有真正了解这儿都产生了甚么事变,这些观点都是从ElliotteRustyHarold编著的《JavaNetworkProgramming》里得来的,该书由OReilly于1997年出书。他在书中提到了Java连网函数库中呈现的很多使人利诱的Bug。以是一旦涉足这些范畴,事变就不是编写代码,然后让它本人运转那末复杂。必定要小心潜伏的圈套!
信息发送到服务器后,我们挪用getInputStream(),并把前往值封装到一个DataInputStream里,以便本人能读取了局。要注重的一件事变是了局以文本行的情势显现在一个TextArea(文本地区)中。为何不复杂地利用getAppletContext().showDocument(u)呢?现实上,这恰是那些圈套中的一个。上述代码能够很好地事情,但假设试图换用showDocument(),几近统统城市中断运转。也就是说,showDocument()的确能够运转,但从POSTtest失掉的前往了局是“ZeroCONTENT_LENGTH”(内容长度为零)。以是不晓得为何缘故原由,showDocument()制止了POST查询向CGI程序的传送。我很难判别这究竟是一个在今后版本里会修复的Bug,仍是因为我的了解不敷(我看过的书对此讲得都很含混)。但不管在哪一种情形下,只需能保持在文本地区里寓目自CGI程序前往的内容,上述程序片运转时就没有成绩。
再举这样一个例子:如果你想对一个数字取绝对值,你会怎么做呢?java的做法是intc=Math.abs(-166);而ruby的做法是:c=-166.abs。呵呵,这就看出了java与ruby的区别。 |
|