在有些情况下,我们可能需要使用到Applet和Servlet通讯,比如客户需要在客户端实时显示服务器端处理器利用率的状况,又或者一个股票交易情况,等等一些实时的系统中。
一般来说客户端的Applet程序同服务器端的通讯可以有下面几种方法:
1、通过Socket建立双向连接。
2、使用RMI
3、使用CORBA
4、webservice
5、使用URLConnection
在这里我们主要讨论使用URLConnection的方法来通过传递一个Object来获取服务器端的一些信息。使用这种方法的好处是,它传递的是Http对象,走的是Http协议,不需要另外开端口,可以穿透防火墙。
前面都是废话,下面正式开始吧
功能:
使用URLConnection的方法,在客户端的Applet程序,实时获取到服务器端Servlet上的处理器利用率信息。其最终的效果图如下:
开发环境:winxp/lomboz-eclipse-emf-gef-jem-I20050526/jdk1.5.0_03/
一、首先创建一个使用lomboz创建一个名称为AppletServletJ2EE项目,如何使用Lomboz做web开发?
请看这篇文章。
二、创建一个CpuUsageInfo类用于保存处理器利用率的信息,里面只有两个属性:处理器名称和利用率的值。注意这个类是可序列化的,请注意这个对象必须执行Serializable接口以使其序列化。此外,任何引用这个对象的其他对象也必须执行Serializable接口,也就是说需要继承自Serializable类,
并且类中serialVersionUID 必不可少而且不能使用自动生成的1L。(也许是JDK版本的问题,反正如果添加,就会有问题,这个问题曾经整整折磨了我一天)。
package com.sundy;
/**/ /**
*
* TODO 获取处理器利用率功能类
*
* @author 刘正伟(sundy)
* @see mailto:sundy26@126.com
* @version 1.0
* @since 2005-6-22
*
* 修改记录:
* 日期 修改人 描述
* -----------------------------------------------------------------------
*/
/**/ /**
* @author sundy
*
*/
import java.io.Serializable;
public class CpuUsageInfo implements Serializable {
//注意这个serialVersionUID可不能少,而且不能使用缺省的1L
static final long serialVersionUID = 3978139846068651413L;
private String cpuId; //cpu ID
private float cpuValule; //windows节点的cpu利用率
public String getCpuId() {
return this.cpuId;
}
public void setCpuId(String value) {
this.cpuId = value;
}
public float getCpuVaule() {
return this.cpuValule;
}
public void setCpuVaule(float value) {
this.cpuValule = value;
}
}
/**/ /**
*
* TODO 获取处理器利用率功能类
*
* @author 刘正伟(sundy)
* @see mailto:sundy26@126.com
* @version 1.0
* @since 2005-6-22
*
* 修改记录:
* 日期 修改人 描述
* -----------------------------------------------------------------------
*/
/**/ /**
* @author sundy
*
*/
import java.io.Serializable;
public class CpuUsageInfo implements Serializable {
//注意这个serialVersionUID可不能少,而且不能使用缺省的1L
static final long serialVersionUID = 3978139846068651413L;
private String cpuId; //cpu ID
private float cpuValule; //windows节点的cpu利用率
public String getCpuId() {
return this.cpuId;
}
public void setCpuId(String value) {
this.cpuId = value;
}
public float getCpuVaule() {
return this.cpuValule;
}
public void setCpuVaule(float value) {
this.cpuValule = value;
}
}
三、创建一个Servlet用来获取处理器利用率信息,并且将CpuUsageInfo的实例作为一个对象传递。你也许还没有意识到HTTP连接也可以用来传输二进制的数据,就象传输文本数据一样,但是事实上每次你从一个web看到图象时或者是下载.zip文件时都在使用这个功能。我们可以利用这个功能并结合被称之为“对象序列”的技术从Servlet向Applet传输完整的Java对象。复杂的数据可以很容易地被传输,你不需要做任何解析和解释。
对象序列允许我们将对象封装到二进制数据流,它可以到达一个OutputStream可以到达的任何地方:磁盘、屏幕或者是在我们的例子中,通过一个HTTP连接到达一个Applet。使用HTTP对象流和使用HTTP文字流的方法几乎一样。我们建立一个到我们的web主机上的Servlet的URL连接并读取其返回的数据。我们将对象封装到ObjectInputStream中。我们可以按照适当的类型读取其中的对象。代码清单如下:
对象序列允许我们将对象封装到二进制数据流,它可以到达一个OutputStream可以到达的任何地方:磁盘、屏幕或者是在我们的例子中,通过一个HTTP连接到达一个Applet。使用HTTP对象流和使用HTTP文字流的方法几乎一样。我们建立一个到我们的web主机上的Servlet的URL连接并读取其返回的数据。我们将对象封装到ObjectInputStream中。我们可以按照适当的类型读取其中的对象。代码清单如下:
/**/
/**
*
* TODO 获取处理器利用率Servlet类,在这个类中,我们使用ObjectOutputStream类将一个对象,作为
* 数据流的形式输出。
*
* @author 刘正伟(sundy)
* @see mailto:sundy26@126.com
* @version 1.0
* @since 2005-6-22
*
* 修改记录:
* 日期 修改人 描述
* -----------------------------------------------------------------------
*/
package com.sundy;
import java.io. * ;
import javax.servlet. * ;
import javax.servlet.http. * ;
public class CpuServlet extends HttpServlet {
private static final long serialVersionUID = 3978139946068651413L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
ObjectOutputStream objStream = new ObjectOutputStream(response.getOutputStream());
CpuUsageInfo cpu = new CpuUsageInfo();
cpu.setCpuId("Total");
float d1 = (float)(100D * Math.random());
cpu.setCpuVaule(d1);
objStream.writeObject(cpu);
objStream.flush();
objStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
*
* TODO 获取处理器利用率Servlet类,在这个类中,我们使用ObjectOutputStream类将一个对象,作为
* 数据流的形式输出。
*
* @author 刘正伟(sundy)
* @see mailto:sundy26@126.com
* @version 1.0
* @since 2005-6-22
*
* 修改记录:
* 日期 修改人 描述
* -----------------------------------------------------------------------
*/
package com.sundy;
import java.io. * ;
import javax.servlet. * ;
import javax.servlet.http. * ;
public class CpuServlet extends HttpServlet {
private static final long serialVersionUID = 3978139946068651413L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
ObjectOutputStream objStream = new ObjectOutputStream(response.getOutputStream());
CpuUsageInfo cpu = new CpuUsageInfo();
cpu.setCpuId("Total");
float d1 = (float)(100D * Math.random());
cpu.setCpuVaule(d1);
objStream.writeObject(cpu);
objStream.flush();
objStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
四、在web.xml中配置Servlet的映射,这个不多说,看配置文件;
<?
xml version="1.0" encoding="ISO-8859-1"
?>
<! DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd" >
< web-app >
< display-name > Struts Logon Application </ display-name >
<!-- Standard Action Servlet Configuration (with debugging) -->
< servlet >
< servlet-name > cpu </ servlet-name >
< servlet-class >
com.sundy.CpuServlet
</ servlet-class >
</ servlet >
<!-- Standard Action Servlet Mapping -->
< servlet-mapping >
< servlet-name > cpu </ servlet-name >
< url-pattern > /cpu </ url-pattern >
</ servlet-mapping >
<!-- The Welcome File List -->
< welcome-file-list >
< welcome-file > index.jsp </ welcome-file >
</ welcome-file-list >
</ web-app >
<! DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd" >
< web-app >
< display-name > Struts Logon Application </ display-name >
<!-- Standard Action Servlet Configuration (with debugging) -->
< servlet >
< servlet-name > cpu </ servlet-name >
< servlet-class >
com.sundy.CpuServlet
</ servlet-class >
</ servlet >
<!-- Standard Action Servlet Mapping -->
< servlet-mapping >
< servlet-name > cpu </ servlet-name >
< url-pattern > /cpu </ url-pattern >
</ servlet-mapping >
<!-- The Welcome File List -->
< welcome-file-list >
< welcome-file > index.jsp </ welcome-file >
</ welcome-file-list >
</ web-app >
配置好之后,先在IE中测试一下看看Servlet好不好用:
在地址栏中输入:
http://localhost:8080/AppletServlet/cpu
如果成功的化,会输出一堆乱码,那就恭喜你,如果出错了,仔细看看web.xml文件有没有配置错误。
五、在Applet程序中接收HTTP流,并将HTTP流转通过ObjectInputStream转换成对应的对象。
package com.sundy.applet;
import java.applet.Applet;
/**/ /**
*
* TODO 获取处理器利用率功能类
*
* @author 刘正伟(sundy)
* @see mailto:sundy26@126.com
* @version 1.0
* @since 2005-6-22
*
* 修改记录:
* 日期 修改人 描述
* -----------------------------------------------------------------------
*/
/**/ /**
* @author sundy
*/
// import java.applet.Applet;
import java.net. * ;
import java.io. * ;
import java.awt. * ;
import java.awt. event . * ;
import com.sundy.CpuUsageInfo;
public class CpuApplet extends Applet implements ActionListener {
private static final long serialVersionUID = 1L;
Button getCpuButton;
TextArea messageText;
public void init() {
//初始化Applet界面
getCpuButton = new Button("Get Cpu");
messageText = new TextArea("chick the button to get cup info/n", 15, 40);
Panel mainp = new Panel();
mainp.add(getCpuButton);
mainp.add(messageText);
getCpuButton.addActionListener(this);
add("Center", mainp);
}
private CpuUsageInfo getCpuInfo() {
try {
URL url = new URL(getCodeBase(), "/AppletServlet/cpu");
//打开Url连接
URLConnection con = url.openConnection();
//获取数据流
ObjectInputStream objStream = new ObjectInputStream(con
.getInputStream());
Object obj = objStream.readObject();
//转换对象
CpuUsageInfo cpu = (CpuUsageInfo) obj;
objStream.close();
return cpu;
} catch (MalformedURLException e) {
messageText.appendText("URL 错误!");
} catch (IOException e) {
messageText.appendText("转换对象错误,是否对象没有继承Serializable");
} catch (ClassNotFoundException e) {
messageText.appendText("没有找到类,无法进行转换");
}
return null;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == getCpuButton) {
CpuUsageInfo cpu = getCpuInfo();
if (cpu != null) {
messageText.appendText(cpu.getCpuId() + ":"
+ cpu.getCpuVaule() + "/n");
} else {
messageText.appendText("没有获取到处理器利用率信息/n");
}
}
}
}
import java.applet.Applet;
/**/ /**
*
* TODO 获取处理器利用率功能类
*
* @author 刘正伟(sundy)
* @see mailto:sundy26@126.com
* @version 1.0
* @since 2005-6-22
*
* 修改记录:
* 日期 修改人 描述
* -----------------------------------------------------------------------
*/
/**/ /**
* @author sundy
*/
// import java.applet.Applet;
import java.net. * ;
import java.io. * ;
import java.awt. * ;
import java.awt. event . * ;
import com.sundy.CpuUsageInfo;
public class CpuApplet extends Applet implements ActionListener {
private static final long serialVersionUID = 1L;
Button getCpuButton;
TextArea messageText;
public void init() {
//初始化Applet界面
getCpuButton = new Button("Get Cpu");
messageText = new TextArea("chick the button to get cup info/n", 15, 40);
Panel mainp = new Panel();
mainp.add(getCpuButton);
mainp.add(messageText);
getCpuButton.addActionListener(this);
add("Center", mainp);
}
private CpuUsageInfo getCpuInfo() {
try {
URL url = new URL(getCodeBase(), "/AppletServlet/cpu");
//打开Url连接
URLConnection con = url.openConnection();
//获取数据流
ObjectInputStream objStream = new ObjectInputStream(con
.getInputStream());
Object obj = objStream.readObject();
//转换对象
CpuUsageInfo cpu = (CpuUsageInfo) obj;
objStream.close();
return cpu;
} catch (MalformedURLException e) {
messageText.appendText("URL 错误!");
} catch (IOException e) {
messageText.appendText("转换对象错误,是否对象没有继承Serializable");
} catch (ClassNotFoundException e) {
messageText.appendText("没有找到类,无法进行转换");
}
return null;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == getCpuButton) {
CpuUsageInfo cpu = getCpuInfo();
if (cpu != null) {
messageText.appendText(cpu.getCpuId() + ":"
+ cpu.getCpuVaule() + "/n");
} else {
messageText.appendText("没有获取到处理器利用率信息/n");
}
}
}
}
六、在web页面中调用Applet程序。
先看index.jsp文件文件,如何使用Applet就不多说了:
先要将Applet程序考到WEB-INF目录外面,在这个例子里面,将Applet放在classes目录下。注意这里需要拷贝一个CpuUsageInfo.class到com.sundy目录下,拷贝CpuApplet.class到com.sundy.applet目录下。
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
>
< html >
< head >
< title > Get Cpu from servlet </ title >
</ head >
< body >
< h1 >
The applet will appear in this web page
</ h1 >
< applet codebase ="./Applet/classes"
code ="com.sundy.applet.CpuApplet"
width = 300
height = 200 >
</ applet >
</ body >
</ html >
< html >
< head >
< title > Get Cpu from servlet </ title >
</ head >
< body >
< h1 >
The applet will appear in this web page
</ h1 >
< applet codebase ="./Applet/classes"
code ="com.sundy.applet.CpuApplet"
width = 300
height = 200 >
</ applet >
</ body >
</ html >
先要将Applet程序考到WEB-INF目录外面,在这个例子里面,将Applet放在classes目录下。注意这里需要拷贝一个CpuUsageInfo.class到com.sundy目录下,拷贝CpuApplet.class到com.sundy.applet目录下。
其路径如下:
好了,在这个例子中,简单介绍了,使用URLConnection的方法,在Applet和Sevlet传递对象,来实现数据的实时获取。