将近半个月的时间研究,终于完成了如题所示的功能,从无到有的整个过程让我惊心动魄!!!

源代码:


由于代码众多,所以......我也无能为力。

使用Java代理来接受Lotus数据所有的数据都是以XML文件来传递,所以数据量会很大。并且有些功能需要添加自定义节点来完成(如已读邮件或未读邮件)。


首先要获得邮件就需要连通Domino服务器,两个方法:使用IOR地址,去该地址下载IOR字符串,再去连接服务器,或者使用服务器域名来连接得到IOR对象,通过IOR对象去连接服务器。得到Session对象


然后一步步向下得到Database。


database = session.getDatabase(session.getServerName(), "mail//"+ userMailName + ".nsf", false);// 一般是用户名



这里需要注意的是第二个参数的分割斜杠如代码所示,因为Lotus用户名为 xx/xxx/xxxx ,所以在直接引用的时候需要进行字符串替换 string.replace("/", "//") 这个时候就得到了所有邮件的数据。这里还需要记住names.nsf


得到View


view = database.getView(MailBoxType);// 一般是邮箱名称。如收件箱


这里需要知道各种邮箱的名称:

收件箱  ---  ($Inbox)

发件箱  ---  ($Sent)

草稿箱  ---  ($Drafts)

星标箱  ---  ($Follow-Up)

删除箱  ---  ($SoftDeletions)

垃圾箱  ---  ($JunkMail)

所有箱  ---  ($All)

如上所示,根据自己所需要的邮箱来设定邮箱的字符串从而得到该邮箱的邮箱视图。


得到Document

邮件会以Document对象进行传递,得到第一个Document,然后下一个Document用第一个Document来作为参数。


view.getNextDocument(document);


但我不建议这样使用,因为Lotus本就以对大型数据处理为特点,数据量大,很大很大。当然主要原因并不是这个,因为我们会发现这样读取数据很麻烦,必须要对其进行循环才能得到想要的某个Document,所以我建议在解析Document之前我们先得到所有邮件的UNID标识,保存在集合里面。然后通过UNID来反读Document,这样当我们想要读取某个中间邮件的时候只需要找到该位置的UNID就可以直接抽取Document数据。


while (document != null) {
	// 保存Unid
	unids.add(document.getUniversalID());

	// 得到下一封邮件
	document = view.getNextDocument(document);
}


将所有的UNID数据存储在List中以便更好的读取想要的数据。这是在解析Document之前做的准备工作。


解析Document
首先要知道我们需要读取哪些内容:

邮件类型,主题,发件人,收件人,抄送人,密送人,主要内容,内嵌图片,表格,附件,未读标记,星标标记,时间

要抽取这些内容,首先就需要知道这些内容的节点。

Form,Subject,Principal,SendTo,CopyTo,BlindCopyTo,Body(包括主要内容,内嵌图片,表格,附件),FollowUpStatus,Reader(自定义节点),PostedDate

这就是以上所有数据的XML节点,我们要得到内容都需要根据这些节点来获取。注意因为是XML内容,所以得到的数据可能为NULL,所以最好在抽取数据前做好判断工作。以免出现空指针报错。


boolean flag = document.hasItem("Form");




邮件类型(Form)


String form = document.getItemValueString("form"); //后面的代码都和这个差不多,只要把参数改成其他节点就行

首先Lotus所有的数据Document都会有一个类型(Form)作为XML开始节点,它会表示这是什么数据(如联系人里面的Form是Person)。在邮件里面有两个类型:普通类型(Memo),回复类型(Reply)。所有的非回复类型都是Memo,只有回复邮件的Document类型为Reply。在邮件类型的判定和对邮件的搜索会使用它。


主题(Subject)收件人(Principal)

代码如上所示

邮件主题,对于每个邮件都会有的类型。


发件人(SendTo),抄送人(CopyTo),密送人(BlindCopyTo)


Vector sendTo = document.getItemValue("SendTo");

在对以上三者进行数据抽取的时候就和String类型的不太一样,因为这些类型得到的数据可能会有多个,所以返回的不是String而是Vector。此时就需要进行数据循环处理。


邮件内容(包括表格,内嵌图片及附件)(Body)


注意此时才是抽取数据真正麻烦的时候,所有的数据都在Body里面,目前我只有两种方法来解决:

1).


String body = document.getItemValueString("Body");

这个方法可以把所有的非内嵌图片,非附件内容全部读取出来,非常好,但是一点,会把表格里面的文字内容也读取出来!!!没错是表格中的内容,不太表格的文字内容,这让我怎么???



2).

通过得到Document的XML数据进行数据抽取,来得到邮件中的文本内容。麻烦麻烦麻烦,真的很麻烦。从richtext节点开始读取,所有的邮件内容都在里面。


两种方法,作为大公司表格可定存在,所以我建议用第二种方法来解决正文的读取。方法就不多说了。


内嵌图片

也是通过XML文件节点数据抽取的方式来解析图片内容,图片类型,图片名称,图片大小。


/**
 * 内嵌图片解析
 */
public static Map<String, String> getPicture(Node node,Map<String, String> content) {

	Node picNode = node.getChildNodes().item(0);

	/**
	 * 图片大小
	 */
	content.put("picture", picNode.getAttributes().getNamedItem("width")
			+ "");
	content.put("picture", picNode.getAttributes().getNamedItem("height")
			+ "");

	picNode = picNode.getChildNodes().item(0);

	/**
	 * 图片类型
	*/
	content.put("picture", picNode.getNodeName());

	/**
	 * 图片数据
	 */
	content.put("picture", picNode.getTextContent());

	return content;
}

这里参数为根节点和Map集合,节点就是通过richtext开始,方法写的很模糊,大家读取XML的时候应该就会清晰一点了。


表格

同上,XML文件可以自己去看看,因为Lotus有五种表格类型,所以我就放弃研究了。大概看了一下,默认类型和四种类型标识:普通(无),带选项卡的表格(tabs),带动画表格(timer),可单击的表格(captions),可规划的表格(compute)。


附件

<span >	</span>Vector vector = richTextItem.getEmbeddedObjects();
<pre name="code" class="java">// 附件个数
	int emSize = vector.size();
	System.out.println(""+emSize);
					
	for (int j = 0; j < vector.size(); j++) {
		EmbeddedObject eo = (EmbeddedObject) vector.elementAt(j);

		if (eo.getType() == EmbeddedObject.EMBED_ATTACHMENT) {

		// 附件名称
		String eoName = eo.getName();
							
		// 附件大小
		int eoSize = eo.getFileSize();
<span >		</span>
<span >		</span>// 附件内容
<span >		</span>inputStream = eo.getInputStream();
System.out.println(eoName+"-"+eoSize);
	<span >	</span>}
<span >	</span>}






得到所以附件的一个集合类型。

星标(FollowUpStatus)

说实话我至今对这个功能不太理解,它不止是标记低级(1),中级(2),高级(3)。读取会简单一点,但是标记则需要一些其他处理。


未读标识(Reader)


// 邮件是否未读标记
// 0 --- 未读
// 1 --- 已读
	String reader = document.getItemValueString("Reader");
		if (reader == null) {
			document.appendItemValue("Reader", "0");
			if (document.save()) {
				/**
				 * 未读标识保存成功
				 */
			} else {
				/**
				 * 未读标识保存失败
				 */
			}

		} else {
			System.out.println("Reader标识:已读邮件");
	<span >	</span>}

因为使用Java代理Lotus接收的邮件好像没有判断是否是新邮件的方法(真心没找到,如果知道的大神们,请给予回复帮助)。所以我在会在发送或接收的时候判断一个自定义节点Reader来判断该邮件是否已读。


以上为邮件所有的数据抽取方法,另外需要注意的是以上所涉及的类都需要在最后释放。

邮件的处理在第二弹详细描述。