用无线设备比如手机上网的时候经常需要通过表单提交一些数据,比如登录操作,通常的情况下服务器端我们采用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);
- }
- }