程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> post是什麼意思

post是什麼意思

編輯:關於JAVA

在許多應用程序中使用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_vector works as easily with POST as it
// does with GET. Written in "pure" 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(int i = 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環境變量尚未設置,所以肯定某個地方出了問題。否則就必須用ANSI C庫函數atoi()將字串轉換成一個整數。這個長度將與new一起運用,分配足夠的存儲空間,以便容納查詢字串(另加它的空中止符)。隨後為cin()調用read()。read()函數需要取得指向目標緩沖區的一個指針以及要讀入的字節數。隨後用空字符(null)中止query_str,指出已經抵達字串的末尾,這就叫作“空中止”。
到這個時候,我們得到的查詢字串與GET查詢字串已經沒有什麼區別,所以把它傳遞給用於CGI_vector的構建器。隨後便和前例一樣,我們可以自由vector內不同的字段。
為測試這個程序,必須把它編譯到主機Web服務器的cgi-bin目錄下。然後就可以寫一個簡單的HTML頁進行測試,就象下面這樣:

 

<HTML>
<HEAD>
<META CONTENT="text/html">
<TITLE>A test of standard HTML POST</TITLE>
</HEAD>
Test, uses standard html POST
<Form method="POST" ACTION="/cgi-bin/POSTtest">
<P>Field1: <INPUT TYPE = "text" NAME = "Field1" 
VALUE = "" size = "40"></p>
<P>Field2: <INPUT TYPE = "text" NAME = "Field2" 
VALUE = "" size = "40"></p>
<P>Field3: <INPUT TYPE = "text" NAME = "Field3" 
VALUE = "" size = "40"></p>
<P>Field4: <INPUT TYPE = "text" NAME = "Field4" 
VALUE = "" size = "40"></p>
<P>Field5: <INPUT TYPE = "text" NAME = "Field5" 
VALUE = "" size = "40"></p>
<P>Field6: <INPUT TYPE = "text" NAME = "Field6" 
VALUE = "" size = "40"></p>
<p><input type = "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
// An applet that sends its data via a CGI POST
import java.awt.*;
import java.applet.*;
import java.net.*;
import java.io.*;

public class POSTtest extends Applet {
  final static int SIZE = 10;
  Button submit = new Button("Submit");
  TextField[] t = new TextField[SIZE];
  String query = "";
  Label l = new Label();
  TextArea ta = new TextArea(15, 60);
  public void init() {
    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] = new TextField(30));
    }
    p.add(l);
    p.add(submit);
    add("North", p);
    add("South", ta);
  }
  public boolean action (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;
  }
} ///:~

⑥:我不得不說自己並沒有真正理解這兒都發生了什麼事情,這些概念都是從Elliotte Rusty Harold編著的《Java Network Programming》裡得來的,該書由O'Reilly於1997年出版。他在書中提到了Java連網函數庫中出現的許多令人迷惑的Bug。所以一旦涉足這些領域,事情就不是編寫代碼,然後讓它自己運行那麼簡單。一定要警惕潛在的陷阱!

信息發送到服務器後,我們調用getInputStream(),並把返回值封裝到一個DataInputStream裡,以便自己能讀取結果。要注意的一件事情是結果以文本行的形式顯示在一個TextArea(文本區域)中。為什麼不簡單地使用getAppletContext().showDocument(u)呢?事實上,這正是那些陷阱中的一個。上述代碼可以很好地工作,但假如試圖換用showDocument(),幾乎一切都會停止運行。也就是說,showDocument()確實可以運行,但從POSTtest得到的返回結果是“Zero CONTENT_LENGTH”(內容長度為零)。所以不知道為什麼原因,showDocument()阻止了POST查詢向CGI程序的傳遞。我很難判斷這到底是一個在以後版本裡會修復的Bug,還是由於我的理解不夠(我看過的書對此講得都很模糊)。但無論在哪種情況下,只要能堅持在文本區域裡觀看自CGI程序返回的內容,上述程序片運行時就沒有問題。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved