用webdav实现从DominoOA到Exchange的日程同步.
在EKP的个人日程中添加日程,可同步到EXCHANGE。
EXCHANGE:微软的邮件服务器平台,早前用于与DOMINO竞争。自带exchange的工作流,提供CDO,WEBDAV等多种开发接口。
适用场景:客户已有或较依赖于EXCHANGE的使用,从EXCHANGE转换到DOMINO的OA平台。
其他同理可实现功能:邮件,通讯录同步等等。基本都可以通过类似此功能范例来实现。
实现技术说明:
WEBDAV,http1.1的扩展协议,可通过此协议对服务器端文件进行上载,查询,版本管理等多项功能。可通过文件流或XML文件来传递请求。微软的EXCHANGE,包括Sharepoint里,都有应用该技术。
ajax:X,可以是自己定义的一般XML,也可以是WebService中的Soap协议的XML,当然,也可以是WEBDAV的XML定义。因此,我们在UI这一层,通过ajax,实现很多意想不到的功能,例如:Exchange集成,通过JS作为控制总线,调用多个异构系统的WS(如众所周知google地图API),做MUSHUP的混合应用,这些应用已经很多了,也是最近web2.0的一个热点。还有,在sharepoint里制作相应的webpart,直接读取list,或文档库的webservice,实现一个可以拖拉拽的门户自定义,或者自定义与Exchange集成的webpart ,也so easy。
问题点:EXCHANGE里对appointment的类型存储的时间是世界时间,所以我在JS里对xml中的时间进行了处理。
代码范例:
function getUTCDateStr(date,time)
{
var dates=date.split("-");
var times=time.split(":");
var utcdate=new Date(dates[0],dates[1],dates[2],times[0],times[1],"00");
utcstr=utcdate.getUTCFullYear()+"-";
if(utcdate.getUTCMonth()<10)
{
utcstr+="0"+utcdate.getUTCMonth()+"-";
}
else
{
utcstr+=utcdate.getUTCMonth()+"-";
}
if(utcdate.getUTCDate()<10)
{
utcstr+="0"+utcdate.getUTCDate()+"T";
}
else
{
utcstr+=utcdate.getUTCDate()+"T";
}
if(utcdate.getUTCHours()<10)
{
utcstr+="0"+utcdate.getUTCHours()+":";
}
else
{
utcstr+=utcdate.getUTCHours()+":";
}
if(utcdate.getUTCMinutes()<10)
{
utcstr+="0"+utcdate.getUTCMinutes();
}
else
{
utcstr+=utcdate.getUTCMinutes();
}
// utcstr=utcdate.getUTCFullYear()+"-"+utcdate.getUTCMonth()+"-"+utcdate.getUTCDate()+"T"+utcdate.getUTCHours()+":"+utcdate.getUTCMinutes();
return utcstr;
}
function SaveToExchange()
{
var strXMLNSInfo = "xmlns:g=\"DAV:\" "
+ "xmlns:e=\"http://schemas.microsoft.com/exchange/\" "
+ "xmlns:mapi=\"http://schemas.microsoft.com/mapi/\" "
+ "xmlns:mapit=\"http://schemas.microsoft.com/mapi/proptag/\" "
+ "xmlns:x=\"xml:\" xmlns:cal=\"urn:schemas:calendar:\" "
+ "xmlns:dt=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\" "
+ "xmlns:header=\"urn:schemas:mailheader:\" "
+ "xmlns:mail=\"urn:schemas:httpmail:\"";
var strCalInfo = "<cal:location>"+document.all.F_Location.value+"</cal:location>"
+ "<cal:dtstart dt:dt=\"dateTime.tz\">"+getUTCDateStr(document.all.F_StartDate.value,document.all.F_StartTime.value)+":00.000Z</cal:dtstart>"
+ "<cal:dtend dt:dt=\"dateTime.tz\">"+getUTCDateStr(document.all.F_EndDate.value,document.all.F_EndTime.value)+":00.000Z</cal:dtend>"
+ "<cal:instancetype dt:dt=\"int\">0</cal:instancetype>"
+ "<cal:busystatus>BUSY</cal:busystatus>"
+ "<cal:meetingstatus>CONFIRMED</cal:meetingstatus>"
+ "<cal:alldayevent dt:dt=\"boolean\">0</cal:alldayevent>"
+ "<cal:responserequested dt:dt=\"boolean\">1</cal:responserequested>"
+ "<cal:reminderoffset dt:dt=\"int\">900</cal:reminderoffset>";
var strHeaderInfo = "<header:to>" + ExUser + "</header:to>";
// Set the subject of the appointment.
var strMailInfo = "<mail:subject>"+document.all.Subject.value+"</mail:subject>"
+ "<mail:htmldescription>"+document.all.Body.value+"</mail:htmldescription>";
var vXML="<?xml version=\"1.0\"?>"
+ "<g:propertyupdate " + strXMLNSInfo + ">"
+ "<g:set><g:prop>"
+ "<g:contentclass>urn:content-classes:appointment</g:contentclass>"
+ "<e:outlookmessageclass>IPM.Appointment</e:outlookmessageclass>"
+ strMailInfo
+ strCalInfo
+ strHeaderInfo
+ "<mapi:finvited dt:dt=\"boolean\">1</mapi:finvited>"
+ "</g:prop></g:set>"
+ "</g:propertyupdate>";
var uri="http://" + ExServer + "/exchange/"+ ExUser + "/日历/"+DocId+".eml";
var Req = new ActiveXObject("Microsoft.XMLHTTP");
Req.open("PROPPATCH", uri, false,ExUser,ExPassword);
Req.setRequestHeader("Content-Type","text/xml");
Req.send(vXML);
}