起点R3使用JAVA获取Domino数据(下篇)
??? 在上篇中介绍了从JAVA中获取Domino数据库中的文档信息,但有一个缺点,就是必须要有本地Notes,即限制了只能在Windows下使用,在有些情况下,可能需要在其他操作系统中通过JAVA获取Domino数据,本文即为介绍在JAVA中使用CORBA实现跨操作系统访问Domino。本文介绍的Domino版本应该要在R5以上,R5以下版本未经验证,无法确认是否可行。注意,本文中需要使用lotus.domino.corba包,网络上找到这个库源码非常不容易,作者也是花费了不少时间才从国外一个小网站上下载到,如果有需要,请联系作者。Corba访问Domino过程比较复杂,大致如下:
String ior = http://127.0.0.1/diiop_ior.txt;Properties props = new Properties(); props.put("org.openorb.orb.core.ORB", "org.openorb.orb.core.ORB"); ORB orb = ORB.init(new String[]{}, props); // 通过 IOR 得到 IObjectServer 对象org.omg.CORBA.Object obj = orb.string_to_object(ior); IObjectServer ios = IObjectServerHelper.narrow(obj); // 通过 IObjectServer 获得 ISession ProtocolVersion maxVersion = new ProtocolVersion(IBase.DOM_MAJOR_MINIMUM_VERSION, IBase.DOM_MINOR_MINIMUM_VERSION); ProtocolVersion minVersion = new ProtocolVersion(IBase.DOM_MAJOR_VERSION,IBase.DOM_MINOR_VERSION); SessionData sd = ios.createSession(maxVersion, minVersion, ((CrawlTask)job.getCrawltask()).getAccount() , ((CrawlTask)job.getCrawltask()).getPassword()); session = sd.sesObject; 通过账号和密码访问登录Domino后获得session,然后通过session获得数据库信息,如下:
// 使用 ISession dbCache = session.getDatabase(sd.serverName, properties.getProperty("database"), false); dCdata = dbCache.db.getAllDocuments();//iDatabase.search("1=1", null, 10); IDatabaseHolder idatabaseholder = new IDatabaseHolder(); IntHolder intholder = new IntHolder(); IDocument document = dCdata.dcObject.getFirstDocMDB(idatabaseholder, intholder); 一样是或得到document,类型为IDocument,dCdata.dcObject即是文档列表,对此对象遍历即可
document = dCdata.dcObject.getNextDocMDB(document ,idatabaseholder, intholder);
对IDocument对象的遍历也和DIIOP也有一些差别:
ItemData[] id = fieldDoc.getData().items;for (int i = 0; i < id.length; i++) {MetaType metaType = new MetaType(id[i].name,String.valueOf(id[i].type)) ;ItemValue item = id[i].values;if (id[i].type == 1280) { //表示是文本metaType.setValue(item.StringValue()) ;} else if (id[i].type == 1024) { //表示是时间DateTime dateTime = item.TimeObject() ;if(dateTime!=null){metaType.setValue(String.valueOf(dateTime.toString())) ;}} else if (id[i].type == 768) { //表示是整型metaType.setValue(String.valueOf(String.valueOf(item.DoubleValue()))) ;} else if (id[i].type == 1) { //表示是rtf域//获得RTF域的附件信息} else{metaType.setValue(item.StringValue()) ;}}类型代码和上篇中介绍的都是一样的,但RTF域的附件信息获取方式不太一样,需要对items[i].RTObject对象进行进一步处理,处理过程如下:
IRichTextItem rtf = items[i].RTObject ;if(item.StringValue()!=null){outputText.getMetadata().add(items[i].name, item.StringValue()) ;}else if(rtf.getValueAsString()!=null){outputText.getMetadata().add(items[i].name, rtf.getValueAsString()) ;}{NameAndObject[] ed = rtf.getEmbeddedObjects() ;if(ed.length>0){for(NameAndObject nameObject : ed){EmbeddedData eo = document.getAttachment(nameObject.name) ;if(eo!=null && eo.embedObject!=null && eo.embedObject.getFileSize()>0){BooleanHolder holder = new BooleanHolder(true); IntHolder inholder = new IntHolder();byte[] data = null ;java.io.ByteArrayOutputStream output = new java.io.ByteArrayOutputStream() ;try{while((data = eo.embedObject.getFile(inholder, holder))!=null && data.length>0){output.write(data) ;}}catch(Exception ex){ex.printStackTrace();}java.io.ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()) ;//获得输入流,自定义后续处理过程input.close() ;}}}}最后是关闭session,调用 session.recycle()。