引言
J2ME(Java 2 Micro Edition)是Java 2的一个组成部分,是一种高度优化的Java运行环境,主要针对消费类电子设备的,例如蜂窝电话、可视电话、数字机顶盒和汽车导航系统等等。即J2ME是为消费电子产品和手持设备量身定制的Java专用版本。
J2ME的出现使开发跨平台的消费类电子产品的应用软件成为可能。Java语言的与平台无关的特性移植到小型电子设备上,允许移动无线设备之间共享应用程序。它提供了基于HTTP的高级Internet协议,使移动电话能以Client/Server方式直接访问Internet的全部信息,从而使得不同的Client访问不同的资源。
随着网络技术的发展,在将来的无线通信时代中,大量的网络应用程序将被开发出来去满足无线移动通讯的要求,而要充分的发挥无线移动通讯设备的通信能力,J2ME网络编程就变得尤为重要。
一、使用Tomcat搭建Web服务器
![](https://p-blog.csdn.net/images/p_blog_csdn_net/aspnet2002web/2008-1-9wl1.bmp)
图1 网络应用模型
绝大多数的网络应用都是将数据信息保存到DB Server(数据库服务器),通过Web Server协调各种客户端的请求与响应,存取数据库中的数据。数据库服务器和Web服务器可能是网络中的1台或多台的设备;客户端可以通过网际中的通用协议(如http协议)对服务器端进行访问,客户端或者是pc上的web浏览器,或者是移动设备,只要能支持网络通讯的协议就应该能够正确获取服务器端的资源。
我们首先介绍一下使用Tomcat搭键web服务器,在安装Tomcat 5。0之前首先要下载
j2sdk 、Tomcat 5.0的安装文件
图2 要准备的安装文件
第1步安装j2sdk 进入欢迎画面
图3 j2SE安装界面1
第2步接受相关协议条款,然后选择Next
图4 j2SE安装界面2
第3步 选择安装路径,默认为c:j2sdk1.4.2_05 ,这里我们不变,选择Next,(这个路径很重要,如果我们改变了,一定要记住)。
图5 j2SE安装界面3
第4步 系统会自动拷贝文件
图6 j2SE安装界面4
第5步 安装完成 单击finish。
图7 j2SE安装界面5
图8 j2SE安装之后的目录结构
第6步 安装Tomcat 5.0,首先进入欢迎界面,单击Next。
图9 Tomcat 安装界面1
第7步 接受相关协议条款,然后选择Next
图10 Tomcat 安装界面2
第8步 选择完全安装Full,然后选择Next
图11 Tomcat 安装界面3
第9步 确定安装目录,这里我们确定为C:Tomcat 5.0,然后选择Next
图12 Tomcat 安装界面4
第10步 确定Web服务器管理员的用户名和密码以及默认的端口,,然后选择Next
用户名 admin
密码 123 (要记住该密码用于对服务器的各种管理)
默认端口 8080
图13 Tomcat 安装界面5
第11步 确定java虚拟机的所在路径,,然后选择Next
路径 C:j2sdk1.4.2_05 (和我们之前安装JDK的路径要一致)
图14 Tomcat 安装界面6
第12步 系统自动拷贝文件。
图15 Tomcat 安装界面7
第13步 安装完成,系统提示是否马上运行,单击Finish,我们会在屏幕的右下角看到Tomcat 5.0的小图标。
图16 Tomcat 安装界面7
第14步 双击屏幕右下角Tomcat 5.0图标,系统会弹出Tomcat运行窗口,在这个窗口中单击Start开启服务,到此Tomcat 5.0安装完成,可以通过再Web浏览器中输入http://127.0.0.1:8080 检测到欢迎的画面
图17 Tomcat 安装界面8
图18 Tomcat 欢迎画面
安装完成Tomcat以后,下面的工作就是要把磁盘上的文件夹共享为互联网中的虚拟目录,用于客户端的访问。我们在D:创建如下的文件夹结构:
D:mygameWeb (这个目录将作为对外部的虚拟目录用来存放共享的各种资源)
图19 虚拟目录结构
在浏览器中单击页面左上第三项 Tomcat Manager,这是系统会弹出一个窗口要求我们输入Tomcat 管理的用户名和密码,输入用户名admin 密码123 后,按确定进入Web服务器管理页面。
图20 用户管理登陆窗口
图21 Tomcat 管理窗口
在管理界面中的Deploy面板我们输入以下信息:
Context Path(optional): /515game (虚拟目录的名称)
XML Configuration file URL:
WAR or Directory URL: file:d:/mygameWeb (真实的文件夹注意格式和大小写不要错)
填写完成以后单击 Deploy 发布虚拟目录
大功告成,我们可以把资源放到d:mygameWeb这个目录下面通过
http://IP地址:8080/515game/资源名称就可以访问这个服务器上的资源了,
如:
http://127.0.0.1:8080/515game/myweb.html
http://127.0.0.1:8080/515game/back0.png
http://127.0.0.1:8080/515game/kk.wav
假如这台主机在公网的IP地址为221.196.125.11 在互联网中可以过以下地址来访问:
http://221.196.125.11:8080/515game/myweb.html
http://221.196.125.11:8080/515game/back0.png
http://221.196.125.11:8080/515game/kk.wav
在j2me中提供了访问网络的相关类,封装到了javax.microedition.io里面提供了相关类,下面我们通过实例介绍如果通过GCF来让j2me的客户端获取Web服务器缎的资源。
二、从Web获取文字信息
import javax.microedition.io. * ;
import java.io. * ;
import javax.microedition.lcdui. * ;
public class getHttp
extends MIDlet {
public void startApp() {
try {
// 打开网络连接
String url = " http://127.0.0.1/515game/myweb.html " ;
StreamConnection sc = (StreamConnection) Connector.open(url);
// 读取数据
InputStream is = sc.openInputStream();
int tmp = 0 ;
String get = "" ;
while (tmp != - 1 ) { // -1代表结束
tmp = is.read();
get = get + ( char ) tmp;
}
is.close();
Form f = new Form(url);
// 解决中文问题
String chinese = new String(get.getBytes( " iso8859-1 " ), " utf-8 " );
f.append(chinese);
Display.getDisplay( this ).setCurrent(f);
// 关闭网络连接
sc.close();
}
catch (Exception e) {}
}
public void pauseApp() {}
public void destroyApp( boolean f) {}
}
三、从Web获取图片信息
import javax.microedition.lcdui. * ;
import javax.microedition.io. * ;
import java.io. * ;
public class testPic
extends MIDlet {
public void startApp() {
try {
// 打开网络连接
String url = " http://127.0.0.1/515game/back0.png " ;
StreamConnection sc = (StreamConnection) Connector.open(url);
// 获取图片
InputStream is = sc.openInputStream();
Image im = Image.createImage(is); // 该方法为MIDP 2.0方法
Form f = new Form(url);
f.append(im);
Display.getDisplay( this ).setCurrent(f);
// 关闭连接
sc.close();
}
catch (Exception e) {}
}
public void pauseApp() {}
public void destroyApp( boolean f) {}
}
四、从Web获取多媒体信息
import javax.microedition.midlet. * ;
import javax.microedition.io. * ;
import java.io. * ;
import javax.microedition.media. * ;
public class getMusic
extends MIDlet {
public void startApp() {
try {
// 打开网络连接
String url = " http://127.0.0.1/515game/kk.wav " ;
StreamConnection sc = (StreamConnection) Connector.open(url);
// 获取声音
InputStream is = sc.openInputStream();
Player p1 = Manager.createPlayer(is, " audio/x-wav " );
p1.start();
// 关闭网络连接
sc.close();
System.out.println( " sound is play " );
}
catch (Exception e) {
e.printStackTrace();
}
}
public void pauseApp() {}
public void destroyApp( boolean f) {}
}
五、基于http的用户登陆系统实现
checkuser.jsp 这个文件放到d: / mygameWeb目录下面
< %
// 得到用户名
String name = request.getParameter( " username " );
// 得到密码
String pass = request.getParameter( " password " );
if (name.equals( " ldh " ))
{
if (pass.equals( " zhm " ))
{
out.print( " welcome " );
}
else
{
out.print( " pass word error " );
}
}
else
{
out.print( " user name error " );
}
%>
// 客户端程序
import javax.microedition.midlet. * ;
import javax.microedition.lcdui. * ;
import javax.microedition.io. * ;
import java.io. * ;
public class logoIN
extends MIDlet
implements CommandListener, Runnable {
public Form f;
public TextField user; // 用户名
public TextField pass; // 密码
public Command c1;
public logoIN() {
f = new Form( " 传奇世界用户登陆 " );
user = new TextField( " 用户名 " , "" , 10 , TextField.ANY);
pass = new TextField( " 密码 " , "" , 8 , TextField.PASSWORD);
f.append(user);
f.append(pass);
c1 = new Command( " 确定 " , Command.SCREEN, 1 );
f.addCommand(c1);
f.setCommandListener( this );
Display.getDisplay( this ).setCurrent(f);
}
public void startApp() {}
public void pauseApp() {}
public void destroyApp( boolean f) {}
public void commandAction(Command c, Displayable dd) {
Thread t = new Thread( this );
t.start(); // 启动线程连结网络
}
// 完成网络请求
public void run() {
try {
// 打开网络
String url = " http://127.0.0.1/515game/checkuser.jsp?username= " +
user.getString() + " &password= " + pass.getString();
// 获取数据
StreamConnection sc = (StreamConnection) Connector.open(url);
InputStream is = sc.openInputStream();
int tmp = 0 ;
String get = "" ;
while ( (tmp = is.read()) != - 1 ) {
get = get + ( char ) tmp;
}
Form f2 = new Form( " 登陆结果 " );
f2.append(get);
Display.getDisplay( this ).setCurrent(f2);
// 关闭网络
sc.close();
}
catch (Exception e) {}
}
}
六、一个网络游戏实例
下面我们通过一个网络猜价格的游戏实例来说明如何通过J2me同服务器端交换数据。
这是一个网络版商品竞猜的实例,客户端输入商品价格,在服务器端负责游戏逻辑的处理。
服务器端代码:
Guess.jsp 这个文件放到d:/ mygameWeb目录下面
String sjg = request.getParameter( " jg " );
int jg = ( int )(Math.random() * 10 );
int userjg = Integer.parseInt(sjg);
if (userjg > jg)
{
out.println( " sorry da le " );
}
if (userjg<jg)
{
out.println( " sorry xiao le " );
}
if (userjg == jg)
{
out.println( " right " );
}
%>
J2me客户端代码:
import javax.microedition.midlet. * ;
import javax.microedition.lcdui. * ;
import javax.microedition.io. * ;
import java.io. * ;
public class GuessGame
extends MIDlet
implements CommandListener, Runnable {
public Form f, f2;
public TextField tf1;
public Display d;
public Command c1, c2;
public GuessGame() {
f = new Form( " 商品竞猜 " );
f2 = new Form( " 竞猜结果 " );
c2 = new Command( " 返回 " , Command.SCREEN, 1 );
f2.addCommand(c2);
f2.setCommandListener( this );
tf1 = new TextField( " 请输入商品价格1-9 " , "" , 1 , TextField.NUMERIC);
f.append(tf1);
c1 = new Command( " 确定 " , Command.SCREEN, 1 );
f.addCommand(c1);
f.setCommandListener( this );
d = Display.getDisplay( this );
}
public void startApp() {
d.setCurrent(f);
}
public void pauseApp() {}
public void destroyApp( boolean f) {}
public void commandAction(Command c, Displayable d) {
if (c == c1) { // 启动网络请求
( new Thread( this )).start();
}
if (c == c2) {
this .d.setCurrent(f);
}
}
public void run() {
try {
// 打开网络连接
String url = " http://127.0.0.1/515game/Guess.jsp?jg= " + tf1.getString();
StreamConnection sc = (StreamConnection) Connector.open(url);
// 获取请求结果
InputStream is = sc.openInputStream();
int tmp = 0 ;
String get = "" ;
while ( (tmp = is.read()) != - 1 ) {
get = get + ( char ) (tmp);
}
for ( int i = 0 ; i < f2.size(); i ++ ) {
f2.delete(i);
}
f2.append(get);
d.setCurrent(f2);
// 关闭网络连接
sc.close();
}
catch (Exception e) {}
}
}