package com.artfess.mail.util; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.artfess.base.attachment.Attachment; import com.artfess.base.attachment.AttachmentService; import com.artfess.base.util.AppUtil; import com.artfess.base.util.Base64; import com.artfess.base.util.BeanUtils; import com.artfess.base.util.FileUtil; import com.artfess.base.util.JsonUtil; import com.artfess.base.util.StringUtil; import com.artfess.base.util.time.DateFormatUtil; import com.artfess.file.model.DefaultFile; import com.artfess.file.persistence.manager.FileManager; import com.artfess.file.util.AppFileUtil; import com.artfess.mail.api.AttacheHandler; import com.artfess.mail.model.Mail; 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.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.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.EmailMessageSchema; 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.AttachmentCollection; import microsoft.exchange.webservices.data.property.complex.EmailAddress; import microsoft.exchange.webservices.data.property.complex.MessageBody; 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.internet.MimeMessage; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.URI; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Exchange邮件服务工具类 * * @author Yang Cheng * @date 2017-02-13 */ public class ExchangeMailUtil { private AttachmentService attachmentService; private String mailServer; private String user; private String password; private String domain; /** * 附件处理接口 */ private AttacheHandler handler; public ExchangeMailUtil(String mailServer, String user, String password) { this.mailServer = "https://"+mailServer+"/EWS/exchange.asmx"; this.user = user; this.password = password; } public ExchangeMailUtil(String mailServer, String user, String password, String domain) { this.mailServer = "https://"+mailServer+"/EWS/exchange.asmx"; this.user = user; this.password = password; this.domain = domain; } /** * 创建邮件服务 * * @return 邮件服务 */ private ExchangeService getExchangeService() { try (ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);){ //用户认证信息 ExchangeCredentials credentials; if (domain == null) { credentials = new WebCredentials(user, password); } else { credentials = new WebCredentials(user, password, domain); } service.setCredentials(credentials); service.setUrl(new URI(mailServer)); return service; } catch (Exception e) {} return null; } /** * 收取邮件 * * @param max 最大收取邮件数 * @param searchFilter 收取邮件过滤规则 * @return * @throws Exception */ public List receive(int max, SearchFilter searchFilter) throws Exception { ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2); 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 = count > max ? max : count; } //循环获取邮箱邮件 ItemView view = new ItemView(count); //按照时间顺序收取 view.getOrderBy().add(ItemSchema.DateTimeReceived, SortDirection.Descending); FindItemsResults findResults; if (searchFilter == null) { findResults = service.findItems(inbox.getId(), view); } else { findResults = service.findItems(inbox.getId(), searchFilter, view); } int size = findResults.getItems().size(); List result = new ArrayList<>(); if(size == 0) { return result; } service.loadPropertiesForItems(findResults, PropertySet.FirstClassProperties); for (Item item : findResults.getItems()) { EmailMessage message = (EmailMessage) item; Mail mail = this.getMail(message); result.add(mail); } return result; } /** * 收取所有邮件 * * @throws Exception */ public List receive(int max) throws Exception { return receive(max, null); } /** * 收取邮件 * * @throws Exception */ public List receive() throws Exception { return receive(0, null); } /** * 收取指定时间以后的邮件 * @param date 指定时间 * @return * @throws Exception */ public List receive(AttacheHandler handler, LocalDateTime date) throws Exception{ this.handler = handler; SearchFilter searchFilter = null; if(date!=null) { Date t = DateFormatUtil.parse(date); searchFilter = new SearchFilter.IsGreaterThan(EmailMessageSchema.DateTimeReceived, t); } return receive(Integer.MAX_VALUE, searchFilter); } /** * 发送带附件的mail * * @param subject 邮件标题 * @param to 收件人列表 * @param cc 抄送人列表 * @param bodyText 邮件内容 * @param attachmentPaths 附件地址列表 * @throws Exception */ public void send(String subject, String[] to, String[] cc, String[] as,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); msg.setBody(body); for (String toPerson : to) { msg.getToRecipients().add(toPerson); } if (BeanUtils.isNotEmpty(cc)) { for (String ccPerson : cc) { if(StringUtil.isNotEmpty(ccPerson)) { msg.getCcRecipients().add(ccPerson); } } } if (BeanUtils.isNotEmpty(as)) { for (String asPerson : as) { if(StringUtil.isNotEmpty(asPerson)) { msg.getCcRecipients().add(asPerson); } } } if (BeanUtils.isNotEmpty(attachmentPaths)) { FileManager fileManager = AppUtil.getBean(FileManager.class); for (String attachmentPath : attachmentPaths) { if(StringUtil.isNotEmpty(attachmentPath)) { ArrayNode attachmentObjs = (ArrayNode) JsonUtil.toJsonNode(attachmentPath); for (JsonNode jsonNode : attachmentObjs) { DefaultFile sysFile = fileManager.get(jsonNode.get("id").asText()); if(BeanUtils.isNotEmpty(sysFile)){ String fileName = sysFile.getFileName()+"."+sysFile.getExtensionName(); if(Attachment.SAVE_TYPE_FOLDER.equals(sysFile.getStoreType())){ String filePath = AppFileUtil.getAttachPath()+File.separator+sysFile.getFilePath(); File file = new File(filePath); if(file.exists()){ InputStream inputStream = new BufferedInputStream(new FileInputStream(file)); byte[] fileBlob = FileUtil.readByte(inputStream); msg.getAttachments().addFileAttachment(fileName,fileBlob); } }else if(Attachment.SAVE_TYPE_DTABASE.equals(sysFile.getStoreType())){ byte[] fileBlob = sysFile.getBytes(); msg.getAttachments().addFileAttachment(fileName,fileBlob); }else if(Attachment.SAVE_TYPE_FTP.equals(sysFile.getStoreType()) || Attachment.SAVE_TYPE_ALIYUN_OSS.equals(sysFile.getStoreType())){ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); attachmentService.download(sysFile, outStream, BeanUtils.isNotEmpty(sysFile)?sysFile.getProp6():""); ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray()); msg.getAttachments().addFileAttachment(fileName,inStream); } } } } } } msg.send(); } /** * 发送不带附件的mail * * @param subject 邮件标题 * @param to 收件人列表 * @param cc 抄送人列表 * @param bodyText 邮件内容 * @throws Exception */ public void send(String subject, String[] to, String[] cc, String[] as,String bodyText) throws Exception { send(subject, to, cc,as, bodyText, null); } /** * 根据EmailMessage获得Mail实体 * * @param message * @return * @throws Exception * @see MimeMessage */ public Mail getMail(EmailMessage message) throws Exception { Mail mail = new Mail(); LocalDateTime sentDate = null; if (message.getDateTimeSent() != null) { Instant instant = message.getDateTimeSent().toInstant(); ZoneId zone = ZoneId.systemDefault(); sentDate = LocalDateTime.ofInstant(instant, zone); } else { sentDate = LocalDateTime.now(); } // 邮件发送时间 mail.setSendDate(sentDate); String subject = message.getSubject(); if(subject!=null){ mail.setSubject(subject); }else { mail.setSubject("无主题"); } if(message.getHasAttachments()) { AttachmentCollection attachments = message.getAttachments(); if(handler!=null) { handler.handle(attachments, mail); } } // 取得邮件内容 String content = message.getBody().toString(); mail.setContent(Base64.getBase64(content)); // 发件人 mail.setSenderAddress(message.getFrom().getAddress()); mail.setSenderName(message.getFrom().getName()); // 接受者 mail.setReceiverAddresses(message.getReceivedBy().getAddress()); mail.setReceiverName(message.getReceivedBy().getName()); // 暗送者 mail = getBccAddressesAndNames(message, mail); // 抄送者 mail = getCcAddressesAndNames(message, mail); return mail; } /** * 获取密送人员存储到mail实体 * @param to * @param message * @return * @throws Exception */ public Mail getBccAddressesAndNames(EmailMessage message,Mail mail) throws Exception { List items = message.getBccRecipients().getItems(); StringBuffer bccAddresses = new StringBuffer(); StringBuffer bccNames = new StringBuffer(); if(items.size()>0){ for (int i = 0; i < items.size(); i++) { if(i==items.size()-1){ bccAddresses.append(items.get(i).getAddress()); bccNames.append(items.get(i).getName()); }else{ bccAddresses.append(items.get(i).getAddress()).append(","); bccNames.append(items.get(i).getName()).append(","); } } } mail.setBcCAddresses(bccAddresses.toString()); mail.setBccName(bccNames.toString()); return mail; } /** * 获取抄送人员存储到mail实体 * @param to * @param message * @return * @throws Exception */ public Mail getCcAddressesAndNames(EmailMessage message,Mail mail) throws Exception { List items = message.getCcRecipients().getItems(); StringBuffer ccAddresses = new StringBuffer(); StringBuffer ccNames = new StringBuffer(); if(items.size()>0){ for (int i = 0; i < items.size(); i++) { if(i==items.size()-1){ ccAddresses.append(items.get(i).getAddress()); ccNames.append(items.get(i).getName()); }else{ ccAddresses.append(items.get(i).getAddress()).append(","); ccNames.append(items.get(i).getName()).append(","); } } } mail.setCopyToAddresses(ccAddresses.toString()); mail.setCopyToName(ccNames.toString()); return mail; } }