Exchange Web Service(EWS) 协议同步邮件
来源:互联网 发布:大数据时代知乎 编辑:程序博客网 时间:2024/04/29 01:33
Exchange Web Service(EWS) 协议
EWS是微软实现的一种客户端和服务器之间的交换信息的协议。Exchange Server提供了包括从电子邮件、会议安排、团体日程管理、任务管理、文档管理、实时会议和工作流等丰富的协作应用。
EWS基于标准的web service, 使用HTTP+XML+SOAP来传输消息的。一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:
- 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
- 可选的 Header 元素,包含头部信息
- 必需的 Body 元素,包含所有的调用和响应信息
- 可选的 Fault 元素所发生错误的信息,提供有关在处理此消息
EWS的SOAP消息,Header中指明使用的EWS版本信息:
<s:Header> <t:RequestServerVersion s:mustUnderstand="1" Version="Exchange2010_SP1"/></s:Header>
Body中是真正的命令信息,指明要调用的接口和使用的参数:
<s:Body> <m:GetFolder> <m:FolderShape> <t:BaseShape>IdOnly</t:BaseShape> <t:AdditionalProperties> <t:FieldURI FieldURI="folder:DistinguishedFolderId"/> </t:AdditionalProperties> </m:FolderShape> <m:FolderIds> <t:DistinguishedFolderId Id="deleteditems"/> </m:FolderIds> </m:GetFolder></s:Body>
当请求成功是,响应的内容也是放在Body当中:
<s:Body> <m:GetFolderResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <m:ResponseMessages> <m:GetFolderResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:Folders> <t:Folder> <t:FolderId Id="AQMkADAwATMwMAItZDAyNi05ODYxLTAwAi0wMAoALgAAA428HhUZWjFJpUSRJeFqnBwBAHQq8eP3dM1JkMChdMfyLSgAAAIBCgAAAA==" ChangeKey="AQAAABYAAAB0KvHj93TNSZDAoXTH8i0oAAB17L8t" /> </t:Folder> </m:Folders> </m:GetFolderResponseMessage> </m:ResponseMessages> </m:GetFolderResponse></s:Body>
EWS有多个实现版本,每个版本支持的请求都描述在以下三个文件中:
- services.wsdl : 定义了客户端和服务器之间支持的消息协议
- Messages.xds: 定义了SOAP消息请求和响应的信息类型
- Types.xds:定义了SOAP消息使用的数据类型
要访问EWS服务器, 可以用这三个文件自动生成soap访问接口,但是生成的接口可读性比较差,使用起来很不方便。所以在我的项目中,我直接拼装SOAP消息来构建我的请求和解析服务器的响应。
在邮箱客户端中, 主要涉及到的操作如下表所示:
可以看到,EWS支持对邮件folder和邮件对象的增删改查,还支持对folder和item的增量同步。这几个操作是邮箱功能的核心操作,从EWS一开始的版本就开始支持,并不存在版本兼容性的问题。
EWS对每一个folder和item对象都维护了一个changeKey,来表示对象的版本。因此,可以通过changeKey是否变化来判断folder或者item是否发生了改变。EWS为了可以方便的让客户端知道服务器有哪些对象发生了改变,对folder提供了SyncFolderHierar接口用于增量同步folder,对item提供了SyncFolderItems用于增量同步item。这两个增量同步的接口使用了SyncState用于标识同步状态, 如果服务器上的数据发生了改变, 则在响应只返回变更的对象,并将最新的SyncState下发给客户端。下面是这两个命令的具体请求和返回数据示例:
SyncFolderHierar Request
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <soap:Body> <SyncFolderHierarchy xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"> <FolderShape> <t:BaseShape>AllProperties</t:BaseShape> </FolderShape> <SyncState>H4sIA=</SyncState> </SyncFolderHierarchy> </soap:Body></soap:Envelope>
SyncFolderHierar Response
<?xml version="1.0" encoding="utf-8" ?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <t:ServerVersionInfo MajorVersion="8" MinorVersion="0" MajorBuildNumber="628" MinorBuildNumber="0" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" /> </soap:Header> <soap:Body> <SyncFolderHierarchyResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"> <m:ResponseMessages> <m:SyncFolderHierarchyResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:SyncState>H4sIAAA==</m:SyncState> <m:IncludesLastFolderInRange>true</m:IncludesLastFolderInRange> <m:Changes> <t:Create> <t:Folder> <t:FolderId Id="AQApAHR=" ChangeKey="AQAAABY" /> <t:ParentFolderId Id="AQApA=" ChangeKey="AQAAAA==" /> <t:FolderClass>IPF.Note</t:FolderClass> <t:DisplayName>NewFolder</t:DisplayName> <t:TotalCount>0</t:TotalCount> <t:ChildFolderCount>0</t:ChildFolderCount> <t:UnreadCount>0</t:UnreadCount> </t:Folder> </t:Create> </m:Changes> </m:SyncFolderHierarchyResponseMessage> </m:ResponseMessages> </SyncFolderHierarchyResponse> </soap:Body></soap:Envelope>
其中IncludesLastFolderInRange节点是告知是否已经返回了所有的变更信息,如果没有,则需要再用新的SyncState再请求多一次,直到IncludesLastFolderInRange节点为true。
SyncFolderItems Request
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"> <s:Header> <t:RequestServerVersion s:mustUnderstand="1" Version="Exchange2010_SP1" /> </s:Header> <s:Body> <m:SyncFolderItems> <m:ItemShape> <t:BaseShape>IdOnly</t:BaseShape> <t:IncludeMimeContent>false</t:IncludeMimeContent> <t:AdditionalProperties> <t:FieldURI FieldURI="item:DateTimeSent" /> </t:AdditionalProperties> </m:ItemShape> <m:SyncFolderId> <t:FolderId Id="AQMkADAwATMwMAItZDAyNi05ODYxLTAwAi0wMAoALgAAA428HhUZWjFJpUSRJeFqnBwBAHQq8eP3dM1JkMChdMfyLSgAAAIBCQAAAA==" /> </m:SyncFolderId> <m:SyncState>H4sIAAAAAAAEAGNgYGcAAotqE0tHE2NTA0ddZ3NHC10TR2djXSdnJ2ddNyMnC2cnczdLU1OD2vBgveDKvOTgksSSVOfEvMSiSgYr0nW65eekpBZ5pjBYkq43LLWoODM/j8GaaK3+QMuKS4JSk1Mzy1JTQjJzU0nwrU9icYlnXnFJYl5yqncqKb71zS9K9SxJzS32zwtOLSpLLSLByXDfhgNxUW5iUTYklrgYGISA0tDwAxkOUskgCJQyAGI9kJrePXKiklGGnktdJqo+zJojw8hQovXx8feSs54TDiwsOf5JVwOkipETiBn4GJhBHG6GoCfHOrpTrngwCAFFeYEYaN1aRgYGX8cAT19HP5AiBjdTtzCQ8gAgVmVAgH9AnIvELwXiTgZMkA00zwyJb2BgYAzEBropBkZmupYWZoa6YK4BEsBwOxMDAwsDg/MDZnZn86B9BwJYpFr185nl2yrt43452fdfahanntrERWEWD</m:SyncState> <m:MaxChangesReturned>20</m:MaxChangesReturned> </m:SyncFolderItems> </s:Body></s:Envelope>
SyncFolderItems Response
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <h:ServerVersionInfo xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="947" MinorBuildNumber="19" Version="V2017_01_07" /> </s:Header> <s:Body> <m:SyncFolderItemsResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <m:ResponseMessages> <m:SyncFolderItemsResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:SyncState>H4sIAAAAAAAEAGNgYGcAAotqE0tHE2NTA0ddZ3NHC10TR2djXSdnJ2ddNyMnC2cnczdLU1OD2vBgveDKvOTgksSSVOfEvMSiSgYr0nW65eekpBZ5pjBYkq43LLWoODM/j8GaaK3+QMuKS4JSk1Mzy1JTQjJzU0nwrU9icYlnXnFJYl5yqncqKb71zS9K9SxJzS32zwtOLSpLLSLByXDfhgNxUW5iUTYklrgYGISA0tDwAxkOUskgCJQyAGI9kJrePXKiklGGnktdJqo+zJojw8hQovXx8feSs54TDiwsOf5JVwOkipETiBn4GJhBHG6GoCfHOrpTrngwCAFFeYEYaN1aRgYGX8cAT19HP5AiBjdTtzCQ8gAgVmVAgH9AnIvELwXiTgZMkA00zwyJb2BgYAzEBropBkZmupYWZoa6YK4BEsBwOxMDAwsDg/MDZnZn86B9BwJYpFr185nlwxyDzC0CWBQuJ2YxK6W7BvHwBzCretwLausPYLZeEhJ0/EQAs8s9saBbtwNY3DZHvGH2U4oIEpUMYA58eDzI1S2AOWTZsiA3zwDm8HtNQU6uAcwRLPeCGpsCmKPcHgd9+h4QgM0hzNx7vwU9egK0YZOnkxdTAJP93qAVf1cCrXZ5X+50lwlo1VG/X8x+5hlOrauAVv2ocZJiAlq1b7fTOi2gVd+2OjEB6QhZU6elQPGoBHenGasYF2G3LAgUaSVT3HcGMNwLYd+tVs/hO1n/X9VcpR972cDBychQzMDQAADqPT+hzwMAAA==</m:SyncState> <m:IncludesLastItemInRange>true</m:IncludesLastItemInRange> <m:Changes> <t:Create> <t:MeetingRequest> <t:ItemId Id="AQMkADAwATMwMAItZDAyNi05ODYxLTAwAi0wMAoARgAAA428HhUZWjFJpUSRJeFqnBwHAHQq8eP3dM1JkMChdMfyLSgAAAIBCQAAAHQq8eP3dM1JkMChdMfyLSgAAAAHQze+AAAA" ChangeKey="CwAAABYAAAB0KvHj93TNSZDAoXTH8i0oAAALvfbi" /> <t:DateTimeSent>2016-09-26T04:36:53Z</t:DateTimeSent> </t:MeetingRequest> </t:Create> <t:Update> <t:MeetingRequest> <t:ItemId Id="AQMkADAwATMwMAItZDAyNi05ODYxLTAwAi0wMAoARgAAA428HhUZWjFJpUSRJeFqnBwHAHQq8eP3dM1JkMChdMfyLSgAAAIBCQAAAHQq8eP3dM1JkMChdMfyLSgAAAAHQze/AAAA" ChangeKey="CwAAABYAAAB0KvHj93TNSZDAoXTH8i0oAAALvfbj" /> <t:DateTimeSent>2016-09-26T04:38:57Z</t:DateTimeSent> </t:MeetingRequest> </t:Update> <t:Delete> <t:MeetingRequest> <t:ItemId Id="AQMkADAwATMwMAItZDAyNi05ODYxLTAwAi0wMAoARgAAA428HhUZWjFJpUSRJeFqnBwHAHQq8eP3dM1JkMChdMfyLSgAAAIBCQAAAHQq8eP3dM1JkMChdMfyLSgAAABaRuP3AAAA"" ChangeKey="CQAAABYAAAB0KvHj93TNSZDAoXTH8i0oAABaYEei" /> </t:MeetingRequest> </t:Delete> </m:Changes> </m:SyncFolderItemsResponseMessage> </m:ResponseMessages> </m:SyncFolderItemsResponse> </s:Body></s:Envelope>
其中IncludesLastItemInRange节点是告知是否已经返回了所有的变更信息,如果没有,则需要再用新的SyncState再请求多一次,直到IncludesLastFolderInRange节点为true。
使用这两个同步的接口,就可以方便的获取到服务器变更的内容。
理论上,同步folder中的邮件列表,使用SyncFolderItems这个命令就足够了,在将SyncState更新到最新状态时,客户端已经同步到了folder中所有的邮件的id,之后便可以拉取所有的邮件的摘要了。但是在移动客户端中,下载所有的邮件并不是非常理智的行为,非常耗费流量和存储空间。因此在移动客户端中,初始化folder时对邮件的同步数目需要进行限制。为了解决这个问题,在移动客户端中,对邮件里列表的同步分为一下三个操作:
- 初始化阶段:获取最新的SyncState,对这个过程中返回的所有邮件id截取最新的n个id进行邮件下载,存储。
- 下拉更新阶段:使用当前存储的SyncState拉取到所有变化的邮件id,全部进行下载存储。
- 加载更多阶段:用当前存储的最旧邮件的发送时间time1,使用findItem命令搜索不晚于time1时间发送的最近n封邮件邮件id,进行下载存储。
结合SyncFolderItems和findItem两个请求,就可以不需要在初始化邮件列表时中同步所有邮件,但是又可以支持加载旧邮件的需求。
- Exchange Web Service(EWS) 协议同步邮件
- Exchange Web Service (EWS) API 使用笔记
- Exchange Web Service (EWS) API 使用笔记
- exchange web service:通过EWS访问Exchange收件箱
- 使用EWS读取Exchange邮件
- EWS操作exchange邮件服务器收发邮件
- 通过exchange web service收发邮件
- Java -- 通过EWS JAVA API读取exchange邮件
- Java -- 通过EWS JAVA API读取exchange邮件
- Windows Server 2008 R2 配置Exchange 2010邮件服务器并使用EWS发送邮件
- 日历和EWS在Exchange
- 收取邮件的协议 : pop3 exchange imap
- Exchange Web Services简单发送邮件
- ews
- .Net 通过EWS操作邮件和会议
- 迁移Lotus 到Exchange 之同步账户和邮件!
- 常见的邮件服务协议之POP3,IMAP, EXCHANGE
- Programmatic access to Exchange 2010 using EWS, SOAP, and Python
- 动态规划(LCS)(POJ 2250 Compromise)
- 字符串统计
- Python 网络编程/(有连接)
- 数值统计
- 如何转载CSDN上的博文
- Exchange Web Service(EWS) 协议同步邮件
- 希尔排序
- 求奇数的乘积
- 冒泡排序
- 求绝对值
- vmware虚拟机克隆
- 平方和与立方和
- Two Sum
- W-23