分享
 
 
 

通过E-mail共享Java对象

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

JDK1.1的新功能--序列化接口(Serializableinterface),简化了对象持久化(Persistence)的实现。以下介绍如何通过SMTPE-mail将对象传送给另一个用户。

摘要:一些应用程序需要以一种非实时的方式(例如旅行指南、错误报告(bugreport)、 时间表(timesheet)等)和其余用户共享对象。Java语言开发工具包(JDK)1.1版提供了一 个重要的功能:java.io.Serializable接口。该技术能让你知道如何序列化一个对象,然 后用e-mail传给其它用户。

对象持久化和用户间对象共享是许多商业解决方案的基础。例如,一个公司可以用从本公司网址启动的Applet来完成一个时间表的制作。同样该公司也可以提供象具有开支报告、旅行指 南、错误报告(bugreport)等功能的Applet。在这些情况下,从Applet的使用者获得的数据需要和负责薪水、付款、旅行房间预订的人们共享。执行这些职能的人们可能分布在不同的 城市和国家,可能工作在不同的时区,不能希望每个工作人员都能象猫头鹰一样在晚上工作以填写这样的表格。相同的信息也不应该重新输入。因此,能够存储并且把这些相关对象传 送到商业应用中是这些applet有别于其它applet的优势。

目前已经有许多方法能实现对象的持久化,例如使用对象数据库和磁盘文件。同样的也有许多办法可以共享对象,例如将数据写入一个套接字,或者实现一个符合CORBA,SOM的模 型。以上这几种方案均有自己的优点,当你设计你的商业解决方案时,需要认真地考虑这些方案。但是,还有一种开销不大但可靠的方法,它使用Internet和Intranet用户能够获取的 技术服务在世界范围传送对象的拷贝。它就是简单邮件传输协议,SMTP。

用E-mail发送Java对象

存储和保存对象的一个简单方法是将对象序列化而后用E-mail将它发送给别的用户。这种 方法有以下优点:

发送的计算机或NC(网络计算机)无需硬盘空间

使用现有的系统传送、排队、发送对象

允许用户使用最喜欢的邮件客户程序来接受邮件

提供简单的机制将同一对象的拷贝分发给许多人

这种方法也有不足之处:

邮件的传送可能因为E-mail主机的关机而被较长时间地延迟。所有的主机都可能出现这 种情况,E-mail服务器的错误恢复优先级通常比数据库服务器低。

邮件的传送不能得到保证--在你的E-mail服务器通知你邮件没有发出时,你不得不重新 发送邮件。

E-mail服务器和POP客户程序的功能不足以处理大量交易信息。

这些不足和你使用的应用程序有关。对于很多商业解决方案,这些不足并不重要。作为一个设计人员,你工作的一部分就是在全面考虑价格、性能和需求的情况下确定系统的最佳整体结构。

使用Java传送对象的四个步骤:

Applet必须依次以下面所列出的四个步骤传送Java对象:

序列化有关对象

发送时选择Base64编码方式对序列化对象编码(RFC1521)

与一个SMTP服务器连接

将该对象传送到这个SMTP服务器

下面将介绍如何用E-mail发送一个假设的"臭虫"报告到公司的质量保证部门。

将对象序列化

JDK1.1提供的一个奇妙的机制,java.io.Serializable接口,能够序列化并且重建对象。 这个接口能使用存储对象(writeObject())和恢复对象(readObject())方法函数。在很多 情况下,使用这个接口很方便,只需实现并且调用这两个方法函数。

以下的代码定义了一个简单的BugReport对象,它实现了最简单的序列化接口。

1 import java.Io.*;

2 public class BugReport implements Serializable {

3 private Float m_SoftwareVersion; // version number from Help.About, e.g. "1.0"

4 private String m_ErrorDescription; // Description of error

5 private int m_Severity; // 1=System unusable - 5=Minor Aesthetic defect

6 public BugReport (Float SoftwareVersion, String ErrorDescription, int Severity) {

7 m_SoftwareVersion = SoftwareVersion;

8 m_ErrorDesctiption = ErrorDescription;

9 m_Severity = Severity;

10 }

11 public BugReport () {} // for reconstituting serialized objects

12 public void save (OutputStream os)

13 throws IOException {

14 try {

15 ObjectOutputStream o = new ObjectOutputStream(os);

16 o.writeObject(this);

17 o.flush();

18 }

19 catch (IOException e) {throw e;}

20 }

21 public BugReport restore (InputStream is)

22 throws IOException, ClassNotFoundException {

23 BugReport RestoredBugReport = null;

24 try {

25 ObjectInputStream o = new ObjectInputStream(is);

26 RestoredBugReport = (BugReport)o.readObject();

27 }

28 catch (IOException e) {throw e;}

29 catch (ClassNotFoundException e) {throw e;}

30 return RestoredBugReport;

31 }

32 }

1使用import语句引入I/O包,包括序列化接口。

2-5定义类中的成员变量,并指出该类实现了序列化接口。

6-10提供一个简单的构造函数

11一个空的构造函数。这个构造函数在重建序列化对象时使用。见以下的例子。

12-20定义一个方法函数,它把对象写入一个已经打开了的ObjectOutputStream。这个方 法函数首先创建一个ObjectOutputStream对象,然后调用writeObject方法函数,最后在 函数返回前显式清空输出缓冲区。

21-30定义一个方法函数,它从一个打开了的InputStream中读入一个BugReport对象。注 意,如果输入流中下一个对象和正在读入对象的类型不一致时,readObject()将会抛出一 个异常。

使用BugReport对象相当简单。譬如我们想要创建一个新的BugReport对象并且把它存入 一个文件,我们会用到以下代码:

1 import java.io.*;

.

.

2 BugReport bug = new BugReport(1.0, "Crashes when spell checker invoked", 2);

3 FileOUtputStream os = new FileOutputStream("MyBug.test");

4 bug.save(os);

很简单,对吗?当然,一旦对象已经被序列化,没有人能阻止你继续操纵对象的状态。上一 个例子中包涵了一个在被写入磁盘时已经存在对象的拷贝。因此你必须要十分谨慎,以防 在对对象做出所有的修改之后没有序列化对象,从而丢失了对象的状态修改信息。

以下是怎样恢复一个对象的拷贝:

1 import java.io.*

.

.

2 FileInputStream fis = new FileInputStream("MyBug.test");

3 BugReport bug = new BugReport().restore(fis);

这更简单!是不是Java的功能越来越强大了?

现在我们修改第二个例子的第3行,使对象被写入一个字节数组而不是一个文件:

1 import java.io.*

.

.

2 BugReport bug = new BugReport(1.0, "Crashes when spell checker invoked", 2);

3 字 节ArrayOutputStream os = new 字 节ArrayOutputStream();

4 bug.save(os);

好了,我们已经构造了一个对象,并且学会把它序列化后放入一个字节OutputStream。然 后,我们将把这个字节OutputStream转化为一个Base64编码的字符串。

.Base64编码

目前的Internet E-mail标准--简单邮件传递协议(SMTP)在RFC821中宣布。对于我们来说, RFC821对邮件的内容规定了两条重要但不难实现的限制。

1.邮件的内容必须全部为7-比特的美国ASCII码。

2.每一行的长度不能超过1000的字符。

因此为了通过SMTP用E-mail进行传送,内存的序列化对象必须转化为和以上相容的格式。

RFC1521提供了一个可行的方案。它定义了邮件的内容部分,使之能包涵多种形式的数 据。这种标准就是目前众所周知的MIME。

按照RFC1521编码过程为:输入是24个比特,输出是4个字节。24个比特输入组从左至右 由3个8比特的输入组形成。这24个比特被看成4个连续的6比特组,而每个6比特输入组被翻 译为Base64码表中的一个数字。

这意味着如果我们有下面的3个字节的输入--xC,xF3,xFF--它将会被转化为如下 的Base64的编码:x3,xF,xF,x3F。

图Base64编码实例

Base64编码似乎有点神秘,但实现它的代码却非常简单,在下面的程序中我们可以看到 这一点。在这个例子中,我们创建了一个新类,Codecs。现在,Codecs有两个方法函数:一 个用来对字符数组编码,一个用来对String类编码。对String类编码的方法函数简单地调 用String类的getBytes()函数,然后对返回的结果字符数组进行编码。我们将增加从Base6解 码至原先格式的方法函数。

1 public class Codecs {

2 private Codecs() {} // do not instantiate this class

3 public final static String base64Encode(String strInput) {

4 if (strInput == null) return null;

5 byte byteData[] = new byte[strInput.length()];

6 strInput.getBytes(0, strInput.length(), byteData, 0);

7 return new String(base64Encode(byteData), 0);

8 }

9 public final static byte[] base64Encode(byte[] byteData) {

10 if (byteData == null) return null;

11 int iSrcIdx; // index into source (byteData)

12 int iDestIdx; // index into destination (byteDest)

13 byte byteDest[] = new byte[((byteData.length+2)/3)*4];

14 for

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有