用ews-java-api讀取郵件正文及附件
阿新 • • 發佈:2021-01-19
技術標籤:java
原本業務使用javamail通過imap協議讀取郵件,後來有個客戶那邊不支援imap協議,需要改為通過微軟的ews(exchange web service)協議讀取。結合網上已有的資料,自己測試了一把,以下是可以成功執行的程式碼
1.maven引入依賴
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.5.6</version> </dependency>
2.程式碼
import microsoft.exchange.webservices.data.core.ExchangeService; import microsoft.exchange.webservices.data.core.PropertySet; import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion; import microsoft.exchange.webservices.data.core.enumeration.property.BasePropertySet; import microsoft.exchange.webservices.data.core.enumeration.property.BodyType; import microsoft.exchange.webservices.data.core.enumeration.property.WellKnownFolderName; import microsoft.exchange.webservices.data.core.enumeration.search.SortDirection; import microsoft.exchange.webservices.data.core.enumeration.service.ConflictResolutionMode; import microsoft.exchange.webservices.data.core.enumeration.service.DeleteMode; import microsoft.exchange.webservices.data.core.service.folder.Folder; import microsoft.exchange.webservices.data.core.service.item.EmailMessage; import microsoft.exchange.webservices.data.core.service.item.Item; import microsoft.exchange.webservices.data.core.service.schema.ItemSchema; import microsoft.exchange.webservices.data.credential.ExchangeCredentials; import microsoft.exchange.webservices.data.credential.WebCredentials; import microsoft.exchange.webservices.data.property.complex.*; import microsoft.exchange.webservices.data.search.FindItemsResults; import microsoft.exchange.webservices.data.search.ItemView; import microsoft.exchange.webservices.data.search.filter.SearchFilter; import javax.mail.event.MailEvent; import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; /** * Exchange郵件服務工具類 */ public class ExchangeMailUtil { private String mailServer;//伺服器地址 private String user; //使用者名稱 private String password; //密碼 private String domain; //域名 /** * 不帶域名的構造器 */ public ExchangeMailUtil(String mailServer, String user, String password) { this.mailServer = mailServer; this.user = user; this.password = password; } /** * 帶域名的構造器 */ public ExchangeMailUtil(String mailServer, String user, String password, String domain) { this.mailServer = mailServer; this.user = user; this.password = password; this.domain = domain; } public static void main(String[] args) throws Exception { // Outlook Web Access路徑通常為/EWS/exchange.asmx ExchangeMailUtil mailUtil = new ExchangeMailUtil("https://mail.xxxx.com/EWS/exchange.asmx", "使用者名稱", "密碼"); // 接收郵件 ArrayList<EmailMessage> mails = mailUtil.receive(10); for (EmailMessage mail : mails) { // 處理附件 GetAttachmentsFromEmail(mail); // 列印結果 System.out.println("郵件標題: " + mail.getSubject()); System.out.println("接收時間: " + mail.getDateTimeReceived()); System.out.println("傳送人: " + mail.getFrom().getName() + ", 地址: " + mail.getFrom().getAddress()); System.out.println("郵件內容:" + mail.getBody()); System.out.println("附件:" + mail.getHasAttachments()); System.out.println("已讀:" + mail.getIsRead()); // 更新已讀 if (!mail.getIsRead()) { mail.setIsRead(true); mail.update(ConflictResolutionMode.AlwaysOverwrite); } } // // 傳送郵件 // String subject = "test"; // String[] to = {"
[email protected]"}; // //抄送人 // String[] cc = {}; // String bodyText = "我就是測試一下發郵件"; // //附件 // String[] attachmentPaths = new String[]{"C:\\test.TXT"}; // try { // mailUtil.send(subject,to,cc,bodyText,attachmentPaths); // System.out.println("傳送成功!"); // } catch (Exception e) { // e.printStackTrace(); // System.out.println("傳送失敗"); // } } /** * 建立郵件服務 * * @return 郵件服務 */ private ExchangeService getExchangeService() { // Exchange版本 ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1); //使用者認證資訊 ExchangeCredentials credentials; if (domain == null) { credentials = new WebCredentials(user, password); } else { credentials = new WebCredentials(user, password, domain); } service.setCredentials(credentials); try { // 連線伺服器 service.setUrl(new URI(mailServer)); } catch (URISyntaxException e) { e.printStackTrace(); } return service; } /** * 收取郵件 * * @param max 最大收取郵件數 * @param searchFilter 收取郵件過濾規則 * @return * @throws Exception */ public ArrayList<EmailMessage> receive(int max, SearchFilter searchFilter) throws Exception { // 獲取服務 ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1); ExchangeCredentials credentials = new WebCredentials(user, password); service.setCredentials(credentials); service.setUrl(new URI(mailServer)); //繫結收件箱,同樣可以繫結發件箱 Folder inbox = Folder.bind(service, WellKnownFolderName.Inbox); //獲取讀取郵件的數量 int count = inbox.getTotalCount(); if (max > 0) { count = Math.min(count, max); } //設定獲取的郵件數量、內容型別 PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties); itempropertyset.setRequestedBodyType(BodyType.Text); ItemView view = new ItemView(count); // view.setPropertySet(itempropertyset); //設定按照時間順序收取 view.getOrderBy().add(ItemSchema.DateTimeReceived, SortDirection.Descending); //查詢郵件 FindItemsResults<Item> findResults; if (searchFilter == null) { findResults = service.findItems(inbox.getId(), view); } else { findResults = service.findItems(inbox.getId(), searchFilter, view); } //MOOOOOOST IMPORTANT: load messages' properties before service.loadPropertiesForItems(findResults, PropertySet.FirstClassProperties); ArrayList<EmailMessage> result = new ArrayList<EmailMessage>(); for (Item item : findResults.getItems()) { // EmailMessage message = (EmailMessage) item; EmailMessage message = EmailMessage.bind(service, item.getId(), itempropertyset); result.add(message); } return result; } /** * 收取指定數量的郵件 * * @throws Exception */ public ArrayList<EmailMessage> receive(int max) throws Exception { return receive(max, null); } /** * 收取所有郵件 * * @throws Exception */ public ArrayList<EmailMessage> receive() throws Exception { return receive(0, null); } /** * 傳送帶附件的mail * * @param subject 郵件標題 * @param to 收件人列表 * @param cc 抄送人列表 * @param bodyText 郵件內容 * @param attachmentPaths 附件地址列表 * @throws Exception */ public void send(String subject, String[] to, String[] cc, String bodyText, String[] attachmentPaths) throws Exception { // 獲取服務 ExchangeService service = getExchangeService(); EmailMessage msg = new EmailMessage(service); // 郵件標題 msg.setSubject(subject); // 郵件內容和型別 MessageBody body = MessageBody.getMessageBodyFromText(bodyText); // body.setBodyType(BodyType.HTML); body.setBodyType(BodyType.Text); msg.setBody(body); // 收件人 for (String toPerson : to) { msg.getToRecipients().add(toPerson); } // 抄送人 if (cc != null) { for (String ccPerson : cc) { msg.getCcRecipients().add(ccPerson); } } // 附件 if (attachmentPaths != null) { for (String attachmentPath : attachmentPaths) { msg.getAttachments().addFileAttachment(attachmentPath); } } msg.send(); } /** * 傳送不帶附件的mail * * @param subject 郵件標題 * @param to 收件人列表 * @param cc 抄送人列表 * @param bodyText 郵件內容 * @throws Exception */ public void send(String subject, String[] to, String[] cc, String bodyText) throws Exception { send(subject, to, cc, bodyText, null); } /** * 獲取附件 * @param mail * @throws Exception */ public static void GetAttachmentsFromEmail(EmailMessage mail) throws Exception { List<Attachment> attachs = mail.getAttachments().getItems(); try { // 判斷是否有附件 if (mail.getHasAttachments()) { // 迭代獲取附件 for (Attachment attach : attachs) { if (attach instanceof FileAttachment) { //接收郵件到臨時目錄 System.out.println(attach.getName()); String dirPath = "C:\\temp\\"; File dir = new File(dirPath); if (!dir.exists()) { dir.mkdir(); } ((FileAttachment) attach).load(dirPath + attach.getName()); } else // Attachment is an item attachment. { ItemAttachment itemAttachment = (ItemAttachment) attach; // Load attachment into memory and write out the subject. // This does not save the file like it does with a file attachment. // This call results in a GetAttachment call to EWS. itemAttachment.load(); System.out.println("Item attachment name: " + itemAttachment.getName()); } } } } catch (Exception e) { e.printStackTrace(); } } }
3.常見問題:
3.1 報401許可權錯誤,一般是使用者名稱或密碼錯誤。
假設郵箱為:[email protected], 使用者名稱則為:robin
3.2 測試URI路徑是否錯誤
直接在瀏覽器輸入uri:https://mail.xxxx.com/EWS/exchange.asmx
正確的話會出現使用者名稱和密碼登入頁面,能成功登入則說明uri、使用者名稱和密碼都無誤。