您的位置:首页精文荟萃软件资讯 → 用J2ME的通用联网框架开发联网的应用程序

用J2ME的通用联网框架开发联网的应用程序

时间:2004/10/8 13:19:00来源:本站整理作者:蓝点我要评论(0)

  尽管目前的无线网络不够理想,手机联网还是给我们开发人员不小的震撼的。毕竟这真的是件神奇的事情,不是吗?本文将讲述如何应用J2ME平台中的通用联网框架开发联网的应用程序。


  首先,必须说明一点:MIDP中规定,任何移动信息设备都必须提供通过http协议的支持,而像其他的通信方式例如socket是设备相关的。有些手机会支持,有些则不支持。这里只大概的说明一下http协议相关的内容,如果不了解这个方面的知识请参考http协议。在javax.microedition.io里面是大量的接口,只有一个connector类,当然在midp2.0里面添加了对push技术的支持,这个留做以后讲。connector类提供的最重要的方法是open()方法,它的返回值为Connection,你可以对他进行转换得到你需要的类型,比如我们以http协议访问服务器


void postViaHttpConnection(String url) throws IOException {
 HttpConnection c = null;
 InputStream is = null;
 OutputStream os = null;
 int rc;


 try {
  c = (HttpConnection)Connector.open(url);


  // Set the request method and headers
  c.setRequestMethod(HttpConnection.POST);
  c.setRequestProperty("If-Modified-Since","29 Oct 1999 19:43:31 GMT");
  c.setRequestProperty("User-Agent","Profile/MIDP-2.0 Configuration/CLDC-1.0");
  c.setRequestProperty("Content-Language", "en-US");


  // Getting the output stream may flush the headers
  os = c.openOutputStream();
  os.write("LIST games\n".getBytes());
  os.flush(); // Optional, getResponseCode will flush


  // Getting the response code will open the connection,
  // send the request, and read the HTTP response headers.
  // The headers are stored until requested.
  rc = c.getResponseCode();
  if (rc != HttpConnection.HTTP_OK) {
   throw new IOException("HTTP response code: " + rc);
  }


  is = c.openInputStream();


  // Get the ContentType
  String type = c.getType();
  processType(type);


  // Get the length and process the data
  int len = (int)c.getLength();
  if (len > 0) {
   int actual = 0;
   int bytesread = 0 ;
   byte[] data = new byte[len];
   while ((bytesread != len) && (actual != -1)) {
    actual = is.read(data, bytesread, len - bytesread);
    bytesread += actual;
   }
   process(data);
   } else {
    int ch;
    while ((ch = is.read()) != -1) {
     process((byte)ch);
    }
   }
  } catch (ClassCastException e) {
   throw new IllegalArgumentException("Not an HTTP URL");
  } finally {
   if (is != null)
    is.close();
   if (os != null)
    os.close();
   if (c != null)
    c.close();
  }
}


  上面的代码是我取自API doc(建议多读一下api doc)。
  下面根据自己的经验说明一下联网中比较重要的问题:


  我们应该明白这是如何工作的,手机发送请求通过无线网络传输到运营商的WAP网关,WAP网关将请求转发到web服务器服务器可以用cgi,asp,servlet/jsp等构建。服务器处理后会把响应转发到WAP网关,WAP网关再把它发送到手机上。WAP网关对我们开发人员来说是透明的我们不用管它。


  如果在你的联网程序上看不到Thread,Runnable这样的字眼,那么你的程序是不能运行的。因为考虑到网络的因素,为了避免操作堵塞。你必须把联网动作放到另外一个线程去运行,而不能在主线程运行。最好当联网的时候提供给用户一个等待的界面比如作一个动画界面。我下面提供的例子中没有用,因为我想把这个单独出来以后谈。


  通常联网的应用程序的界面是比较多的,最好我们使用MVC的模式来实现界面的导航。


  考虑好你想如何传递你数据,这一点是非常重要的。你可以用GET方法也可以使用POST方法,推荐后者。因为get方法只能是通过URL编码的传输。而POST更加灵活,配合DataInputStream、DataOutputStream来使用更是方便。必须清楚我们如何接受数据是跟数据如何发送过来相关的,例如在client端writeUTF(message);writeInt(4);writeBoolean(true),那么接受就应该readUTF();readInt();readBoolean();如果发送过来数据长度是可用的,那么我们可以建立一个适当的数组来接受,如果不可用我们就要一个适当容量的数组来接受。


  下面我提供一个实例来说明以上的问题,在应用程序中我们输入任意字符,通过连接server得到响应并显示出来。server我用servlet写的非常简单,只是在受到的内容后面加上“haha”,程序我安装到自己的手机上运行没有任何问题,就是GPRS网络不够快。Server是tomcat5实现的,关于如何部署servlet的问题超出了本文的讨论范围。我只提供代码,推荐用Eclipse+Lomboz开发j2ee程序。


/*
* Created on 2004-7-5
*
* TODO To change the template for this generated file go to Window -
* Preferences - Java - Code Generation - Code and Comments
*/
package com.north;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author P2800
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Generation - Code and Comments
*/
public class MyServlet extends HttpServlet {
 protected void doGet(HttpServletRequest request,
 HttpServletResponse response) throws ServletException, IOException {
  DataInputStream dis = new DataInputStream(request.getInputStream());
  String result = dis.readUTF();
  DataOutputStream dos = new DataOutputStream(response.getOutputStream());
  dos.writeUTF(result+"haha");
  dos.close();
  dis.close();
  //TODO Method stub generated by Lomboz
 }
 protected void doPost(HttpServletRequest request,
  HttpServletResponse response) throws ServletException, IOException {
   doGet(request,response);
   //TODO Method stub generated by Lomboz
  }
}


  联网的时候一定按照如下的流程做


  1、建立连接,设置传输方式推荐POST,设置方法头


  2、打开输出流,传输数据给服务器


  3、判断相应的状态码,进入不同流程控制,注意错误处理。如果OK则开始接受数据


  4、关闭连接和流


  下面是客户端的代码,对错误处理没有考虑太多。一共是5个class


import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
/*
* Created on 2004-7-4
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/


/**
* @author P2800
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class HttpCommMIDlet extends MIDlet
{


private UIController uicontroller;
/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#startApp()
*/
protected void startApp() throws MIDletStateChangeException
{
 // TODO Auto-generated method stub
 uicontroller = new UIController(this);
 uicontroller.init();
}


/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#pauseApp()
*/
protected void pauseApp()
{
 // TODO Auto-generated method stub
}


/* (non-Javadoc)
* @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
*/
protected void destroyApp(boolean arg0) throws MIDletStateChangeException
{
 // TODO Auto-generated method stub
}


}


import java.io.IOException;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;


/*
* Created on 2004-7-4
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/


/**
* @author P2800
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class UIController
{
 private HttpCommMIDlet midlet;
 private InputCanvas inputUI;
 private DisplayCanvas displayUI;
 private Display display;
 private HttpCommHandler httpHandler;


/**
*
*/
public UIController(HttpCommMIDlet midlet)
{
 this.midlet = midlet;
 // TODO Auto-generated constructor stub
}


public static class EventID
{
 public static final int CONNECT_TO_SERVER = 0;
 public static final int DISPLAY_BACK_TO_INPUT = 1;
}


public void init()
{
 display = Display.getDisplay(midlet);
 httpHandler = new HttpCommHandler(
  "http://222.28.218.222:8088/http/myservlet");
 inputUI = new InputCanvas(this);
 displayUI = new DisplayCanvas(this);
 display.setCurrent(inputUI);
}


public void setCurrent(Displayable disp)
{
 display.setCurrent(disp);
}


public void handleEvent(int EventID, Object[] obj)
{
 new EventHandler(EventID, obj).start();
}


private class EventHandler extends Thread
{
 private int eventID;
 private Object[] obj;
 private Displayable backUI;


 public EventHandler(int eventID, Object[] obj)
 {
  this.eventID = eventID;
  this.obj = obj;
 }


public void run()
{
 synchronized (this)
 {
  run(eventID, obj);
 }
}


private void run(int eventID, Object[] obj)
{
 switch (eventID)
 {
  case EventID.CONNECT_TO_SERVER:
  {
   try
   {
    String result = httpHandler.sendMessage((String) obj[0]);
    displayUI.init(result);
    setCurrent(displayUI);
    break;
   } catch (IOException e)
   {
   }
  }
  case EventID.DISPLAY_BACK_TO_INPUT:
  {
   setCurrent(inputUI);
   break;
  }
  default:
   break;
  }
 }
};


}


import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;


/*
* Created on 2004-7-4
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/


/**
* @author P2800
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class InputCanvas extends Form implements CommandListener
{
 private UIController uicontroller;
 private TextField inputField;
 private StringItem result;
 public static final Command okCommand = new Command("OK", Command.OK, 1);


 public InputCanvas(UIController uicontroller)
 {
  super("Http Comunication");
  this.uicontroller = uicontroller;
  inputField = new TextField("Input:", null, 20, TextField.ANY);
  this.append(inputField);
  this.addCommand(okCommand);
  this.setCommandListener(this);
 }


/*
* (non-Javadoc)
*
* @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command,
* javax.microedition.lcdui.Displayable)
*/
public void commandAction(Command arg0, Displayable arg1)
{
 // TODO Auto-generated method stub
 if (arg0 == okCommand)
 {
  String input = inputField.getString();
  uicontroller.handleEvent(UIController.EventID.CONNECT_TO_SERVER,
  new Object[] { input });
 }
}


}


import java.io.*;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;


/*
* Created on 2004-7-4
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/


/**
* @author P2800
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class HttpCommHandler
{
 private String URL;
 public HttpCommHandler(String URL)
 {
  this.URL = URL;
 }


 public String sendMessage(String message) throws IOException
 {
  HttpConnection httpConn;
  DataInputStream input;
  DataOutputStream output;
  String result;
  try
  {
   httpConn = open();
   output = this.openDataOutputStream(httpConn);
   output.writeUTF(message);
   output.close();
   input = this.openDataInputStream(httpConn);
   result = input.readUTF();
   closeConnection(httpConn,input,output);
   return result;
  }
 finally
 {
  }
}


public HttpConnection open() throws IOException
{
 try
 {
  HttpConnection connection = (HttpConnection) Connector.open(URL);
  connection.setRequestProperty("User-Agent", System
.getProperty("microedition.profiles"));
  connection.setRequestProperty("Content-Type",
"application/octet-stream");
  connection.setRequestMethod(HttpConnection.POST);
  return connection;
 } catch (IOException ioe)
 {
  throw ioe;
 }
}


private DataInputStream openDataInputStream(HttpConnection conn)
throws IOException
{
 int code = conn.getResponseCode();
 if (code == HttpConnection.HTTP_OK)
 {
  return conn.openDataInputStream();
 } else
 {
  throw new IOException();
 }
}


private DataOutputStream openDataOutputStream(HttpConnection conn)
throws IOException
{
 return conn.openDataOutputStream();
}


private void closeConnection(HttpConnection conn, DataInputStream dis,
DataOutputStream dos)
{
 if(conn!= null)
 {
  try
  {
   conn.close();
  }
  catch(IOException e)
  {}
 }
 if(dis!=null)
 {
  try
  {
   dis.close();
  }
  catch(IOException e)
  {}
 }
 if(dos!=null)
 {
  try
  {
   dos.close();
  }
  catch(IOException e)
  {}
 }
}


}


 import javax.microedition.lcdui.Command;
 import javax.microedition.lcdui.CommandListener;
 import javax.microedition.lcdui.Displayable;
 import javax.microedition.lcdui.Form;
 import javax.microedition.lcdui.StringItem;


 /*
  * Created on 2004-7-6
  *
  * TODO To change the template for this generated file go to
  * Window - Preferences - Java - Code Style - Code Templates
 */


 /**
  * @author P2800
  *
  * TODO To change the template for this generated type comment go to Window -
  * Preferences - Java - Code Style - Code Templates
 */
 public class DisplayCanvas extends Form implements CommandListener
 {
  private UIController uicontroller;
  private StringItem result;
  private int index = 0;
  private boolean first = true;
  public static Command backCommand = new Command("Back", Command.BACK, 2);


  public DisplayCanvas(UIController uicontroller)
  {
   super("Result");
   this.uicontroller = uicontroller;
   result = new StringItem("you have input:", null);
   this.addCommand(backCommand);
   this.setCommandListener(this);
  }


 public void init(String message)
 {
  if (first)
  {
   result.setText(message);
   index = this.append(result);
   first = false;
  }
  else
  {
   this.delete(index);
   result.setText(message);
   this.append(result);
  }
 }


 /*
  * (non-Javadoc)
  *
  * @see   javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command,
  * javax.microedition.lcdui.Displayable)
 */
 public void commandAction(Command arg0, Displayable arg1)
 {
  // TODO Auto-generated method stub
  uicontroller.handleEvent(UIController.EventID.DISPLAY_BACK_TO_INPUT,null);
 }
}


相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本