72.JAVA编程思想——P O S T 的概念

72.JAVA编程思想——P O S T 的概念

在许多应用程序中使用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 中读入数据:

1     C代码

#include <iostream.h>

#include "CGITools.h"

void main() {

    cout << "Content-type: text/plain\n"<< endl;

// For a CGI "POST," the server puts the length

// of the content string in the environment

// variable CONTENT_LENGTH:

    char* clen = getenv("CONTENT_LENGTH");

    if (clen == 0) {

        cout << "Zero CONTENT_LENGTH" << endl;

        return;

    }

    int len = atoi(clen);

    char* query_str = new char[len+ 1];

    cin.read(query_str, len);

    query_str[len] = '\0';

    CGI_vector query(query_str);

// Test: dump all names and values

    for (inti = 0; i < query.size(); i++)

        cout << "query[" << i << "].name() = ["<< query[i].name() << "], "

                << "query["<< i << "].value() = [" << query[i].value() << "]"

                << endl;

    delete query_str; // Release storage

}///:~

getenv()函数返回指向一个字串的指针,那个字串指示着内容的长度。若指针为零,表明CONTENT_LENGTH 环境变量尚未设置,所以肯定某个地方出了问题。否则就必须用ANSIC 库函数atoi()将字串转换成一个整数。这个长度将与new一起运用,分配足够的存储空间,以便容纳查询字串(另加它的空中止符)。随后为cin()调用read()。read()函数需要取得指向目标缓冲区的一个指针以及要读入的字节数。随后用空字符(null)中止query_str,指出已经抵达字串的末尾,这就叫作“空中止”。到这个时候,我们得到的查询字串与GET 查询字串已经没有什么区别,所以把它传递给用于CGI_vector 的构建器。随后便和前例一样,我们可以自由vector 内不同的字段。

2     JAVA代码

import java.awt.*;

import java.applet.*;

import java.net.*;

import java.io.*;

public class POSTtest extends Applet {

    final staticintSIZE= 10;

    Button submit = new Button("Submit");

    TextField[] t = new TextField[SIZE];

    String query = "";

    Label l = new Label();

    TextArea ta = new TextArea(15, 60);

 

    public voidinit() {

        Panel p = new Panel();

        p.setLayout(new GridLayout(t.length + 2, 2));

        for (int i = 0; i < t.length; i++) {

            p.add(new Label("Field " + i + " ", Label.RIGHT));

            p.add(t[i] = newTextField(30));

        }

        p.add(l);

        p.add(submit);

        add("North", p);

        add("South", ta);

    }

 

    public booleanaction(Event evt,Object arg){

        if (evt.target.equals(submit)) {

            query = "";

            ta.setText("");

            // Encode the query from the field data:

            for (int i = 0; i < t.length; i++)

                query += "Field" + i + "=" + URLEncoder.encode(t[i].getText().trim()) + "&";

            query += "submit=Submit";

            // Send the name using CGI's POST process:

            try {

                URL u = new URL(getDocumentBase(), "cgi-bin/POSTtest");

                URLConnection urlc = u.openConnection();

                urlc.setDoOutput(true);

                urlc.setDoInput(true);

                urlc.setAllowUserInteraction(false);

                DataOutputStream server = new DataOutputStream(urlc.getOutputStream());

                // Send the data

                server.writeBytes(query);

                server.close();

                // Read and display the response. You

                // cannot use

                // getAppletContext().showDocument(u);

                // to display the results as a Web page!

                DataInputStream in = new DataInputStream(urlc.getInputStream());

                String s;

                while ((s = in.readLine()) != null) {

                    ta.appendText(s + "\n");

                }

                in.close();

            } catch (Exception e) {

                l.setText(e.toString());

            }

        } else

            return super.action(evt, arg);

        return true;

    }

} /// :~

信息发送到服务器后,我们调用getInputStream(),并把返回值封装到一个DataInputStream 里,以便自己能读取结果。要注意的一件事情是结果以文本行的形式显示在一个TextArea(文本区域)中。为什么不简单地使用getAppletContext().showDocument(u)呢?事实上,这正是那些陷阱中的一个。上述代码可以很好地工作,但假如试图换用showDocument(),几乎一切都会停止运行。也就是说,showDocument()确实可以运行,但从POSTtest 得到的返回结果是“Zero CONTENT_LENGTH”(内容长度为零)。所以不知道为什么原因,showDocument()阻止了POST 查询向CGI 程序的传递。我很难判断这到底是一个在以后版本里会修复的Bug,还是由于我的理解不够(我看过的书对此讲得都很模糊)。但无论在哪种情况下,只要能坚持在文本区域里观看自CGI 程序返回的内容,上述程序片运行时就没有问题。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值