用無線設備比如手機上網的時候經常需要通過表單提交一些數據,比如登錄操作,通常的情況下服務器端我們采用Servlet和CGI來執行這些操作。
CLDC作為受限設備的基本配置通常會提供通用的連接框架給開發者連進行網絡開發。另外MIDP還提供HttpConnection的接口,這個接口是javax.microedition.io的一部分,這裡面定義了最基本的HTTP連接需要的方法和常量。
HTTP編程的原理
HTTP協議是一個請求-相應的應用協議,協議規定請求發出前各個參數必須事先設置。比如當用戶點擊表單的提交按鈕後表單內填入的內容會作為請求的一部分發送給服務器端。
請求的方法類型
目前有兩種方法可以用來向服務器端提交請求:GET和POST。這兩種方法決定數據如何遞交給服務器。
采用GET方式要遞交的值作為URL的一部分發送給服務器端,其遞交的值將成為環境變量QUERY_STRING。
采用POST方式遞交的值作為一個輸入流發送給服務器端,其流的長度會放在CONTENT_LENGTH裡。
相對兩種方法POST方法更安全一些,通過POST方法也可以傳輸多種數據。
利用GET方式遞交信息的例子
如下是一個用GET方式遞交表單的HTML例子:
action="http://www.somesite.com/cgi-bin/getgrade.cgi"
method="GET">
Student#:
表單提交給http://www.somesite.com/cgi-bin/getgrade.cgi,當用戶輸入一個學號比如123333,點擊 Retrieve Marks按鈕後表單的數據將作為URL的一部分發送給CGI程序。遞交的地址為http://www.somesite.com/cgi-bin /gergrade.cgi?idnum=123333。用POST方式遞交數據時輸入的數值將作為分段的輸入流發送給服務器。
GET方式用戶輸入中帶有空格時這些空格將被(+)取代,當用戶一次要遞交多個數值時這些數值用(&)分割。
Servlet編程原理
Servlet和CGI相似,Servlets支持請求、響應的編程方式,當一個客戶端發送一個請求給服務器,服務器將這個請求發送給Servlet。Servlet組織一個響應發回給客戶端。Servlet和CGI不同的是,Servlet是對多次請求使用一個進程處理。
當客戶端遞交了一個請求,Servlet 的 service方法就被調用並將請求傳遞給request和response。首先Servlet判斷請求是post還是get方式,並決定用HttpServlet.doGet還是HttpServlet.doPost方法來處理這個請求。這兩個方法都將調用HttpServletRequest和HttpServletResponse。
通過MIDlet激活CGI腳本
了解了基本的HTTP GET,POST和Servlets之後,讓我們來看一個例子。第一個例子是用來說明如何用MIDlet通過POST方式激活一個CGI腳本。
例子中當打開了pgrade.cgi這個CGI的連接後跟著打開可輸出和輸入流。輸入的內容通過output流發送。得到的響應通過input流獲得。 CGI腳本是用PERL寫的,腳本中獲得學號後在數據庫中查找此學號的記錄,如果找到就返回相關的信息給請求的客戶端。因為在MIDlet裡並沒有表單可用於提交,所以內容要通過寫流的方法實現。下面是MIDlet的代碼。
- import java.io.*;
- import javax.microedition.io.*;
- import javax.microedition.lcdui.*;
- import javax.microedition.midlet.*;
- /**
- * An example MIDlet to invoke a CGI script
- * using the POST method.
- **/
- public class PostMidlet extends MIDlet {
- private Display display;
- String url = "http://somesite.com/cgi-bin/pgrade.cgi";
- public PostMidlet() {
- display = Display.getDisplay(this);
- }
- //Initialization. Invoked the MIDlet activates.
- public void startApp() {
- try {
- getGrade(url);
- } catch (IOException e) {
- System.out.println("IOException " + e);
- e.printStackTrace();
- }
- }
- //Pause, discontinue ....
- public void pauseApp() { }
- //Destroy must cleanup everything.
- public void destroyApp(boolean unconditional) { }
- //Retrieve a grade.
- void getGrade(String url) throws IOException {
- HttpConnection c = null;
- InputStream is = null;
- OutputStream os = null;
- StringBuffer b = new StringBuffer();
- TextBox t = null;
- try {
- c = (HttpConnection)Connector.open(url);
- c.setRequestMethod(HttpConnection.POST);
- c.setRequestProperty("IF-Modified-Since", "20 Jan 2001 16:19:14 GMT");
- c.setRequestProperty("User-Agent", "Profile/MIDP-1.0 Configuration/CLDC-1.0");
- c.setRequestProperty("Content-Language", "en-CA");
- os = c.openOutputStream();
- // send request to the CGI script
- String str = "name=163748";
- byte postmsg[] = str.getBytes();
- for(int i=0; < postmsg.length;i++) {
- os.write(postmsg[i]);
- }
- os.flush();
- //receive response and display in a text box.
- is = c.openDataInputStream();
- int ch;
- while((ch = is.read()) != -1) {
- b.append((char) ch);
- System.out.println((char)ch);
- }
- t = new TextBox("Final Grades", b.toString(), 1024, 0);
- } finally {
- if(is!= null) {
- is.close();
- }
- if(os != null) {
- os.close();
- }
- if(c != null) {
- c.close();
- }
- }
- display.setCurrent(t);
- }
- }