获取监控联系人下发来的邮箱附件并下载到服务器本地

private static final Logger log = LoggerFactory.getLogger(ReceiveMail.class);

    // 账号
    @Value("${mail.connect.username}")
    private String user;

    // 密码
    @Value("${mail.connect.password}")
    private String password;

    @Autowired
    private  MailUtil mailUtil;


    @Autowired
    private ITmsCompanyService iTmsCompanyService;

    @Autowired
    private IOrderFileService orderFileService;

    @Autowired
    private ISysUserService  sysUserService;

    @Test
    public void readMail() throws Exception {
        AjaxResult ajaxResult =null;
        Message[] messages = mailUtil.getPopMessages(user,password);
        for (Message message : messages) {
            //获取发送地址
            String addressUser = mailUtil.getFrom(message);

            List<TmsCompany> list= iTmsCompanyService.selectByMail(addressUser);
            if (list.size()<=0) {
                log.info("当前邮件的发件人{}不是我们要监控的对象", addressUser);
                continue ;
            }
            Long companyId = list.get(0).getCompanyId();
            String companyName = list.get(0).getCompanyName();
            if (!mailUtil.isContainAttach((Part) message)) {
                log.info("发件人满足要求但是附件为空,不满足我们监控的需求!");
                continue;
            }
            try {
                List<MailAttachment> mailAttachments = new ArrayList<>();
                mailUtil.getAttachment(message, mailAttachments);
                for (MailAttachment mailAttachment : mailAttachments) {
                    //检查文件命名是否无误
                    boolean b = mailUtil.checkoutFileName(mailAttachment.getName(), companyId.toString());
                    if (b) {
                        log.info("附件命名有误,导入订单操作取消!");
                        continue;
                    }
                    if (mailAttachment.getInputStream()!=null) {
                        List<SysUser> sysUsers = sysUserService.selectByCompanyId(companyId);
                        if (sysUsers.size()<=0) {
                            continue;
                        }
                        //将文件从邮箱附件保存到本地
                        File fileExcel = mailUtil.saveFile(mailAttachment, companyId);

                    }

                }

            }
            catch (Exception ignore) {
                ignore.printStackTrace();
            }
        }
        mailUtil.close();
    }

邮件工具类


import com.alibaba.fastjson.JSONObject;
import com.fanlyun.admin.biz.mail.MailAttachment;
import com.fanlyun.common.constant.Constants;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import com.sun.mail.pop3.POP3Folder;
import com.sun.mail.pop3.POP3Store;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import java.io.*;
import java.util.*;

/**
 * @author jiangyw
 * @date 2019/1/7 19:29
 * <p>
 * 处理邮件工具类
 * 接收/发送服务器根据不同邮箱有不同的地址
 * 在邮箱设置里都可找到
 */
@Component
public class MailUtil {


    private static final Logger log = LoggerFactory.getLogger(MailUtil.class);

    // 发送服务器
    private static final String SEND_SMTP_HOST = "smtp.exmail.qq.com";
    private static final int SEND_SMTP_PORT = 465;

    // 接收服务器
    private static final String RECEIVE_IMAP_HOST = "imap.exmail.qq.com";
    private static final int RECEIVE_IMAP_PORT = 993;

    private static final String RECEIVE_POP_HOST = "pop.exmail.qq.com";
    private static final int RECEIVE_POP_PORT = 110;


    private IMAPFolder imapFolder = null;
    private IMAPStore imapStore = null;

    private POP3Store pop3Store = null;
    private POP3Folder pop3Folder = null;

    //附件保存路径
    @Value("${mail.receive.saveUrl}")
    private String saveUrl;

    //附件保存路径
    @Value("${mail.receive.time}")
    private int time;


    /**
     * 将附件保存下来
     *
     * @param
     * @param companyId
     * @throws IOException
     */
    public File saveFile(MailAttachment mailAttachment, Long companyId) throws IOException {
        String fileName = mailAttachment.getName();
        InputStream inputStream = mailAttachment.getInputStream();
        File file = new File(saveUrl + companyId);
        //如果文件夹不存在则创建
        if (!file.exists() && !file.isDirectory()) {
            file.mkdir();
        }
        //文件保存路径
        long l = System.currentTimeMillis();
        String[] split = fileName.split("\\.");
        String pathName=saveUrl +companyId+File.separator+ split[0]+"_"+l+"."+split[1];
        File fileExcel = new File(pathName);
        FileOutputStream outputStream = new FileOutputStream(fileExcel);
        int len;
        byte[] bytes = new byte[1024];
        while ((len = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);
            outputStream.flush();
        }
        inputStream.close();
        outputStream.close();
        return  fileExcel;
    }


    /***
     * 判断文件命名是否符合条件
     * @param fileName
     * @param companyId
     * @return
     */
    public boolean checkoutFileName(String fileName, String companyId) {
        boolean pan = false;
        if (!fileName.endsWith(Constants.XLSX)) {
            log.info("该附件【{}】文件格式不符合条件,无法导入", fileName);
            pan = true;
        }
        String[] s = null;
        try {
            String[] split = fileName.split("\\.");
            fileName = split[0];
            s = fileName.split(Constants.EMAIL_UNDERLINE);
            if (!s[0].equals(Constants.EMAIL_PREFIX)) {
                log.info("该附件【{}】文件命名不符合条件,前缀命名不符合规范,无法导入", fileName);
                pan = true;
            }
            if (!s[1].equals(companyId)) {
                log.info("该附件【{}】文件命名不符合条件,公司Id查询失败,无法导入", fileName);
                pan = true;
            }
        } catch (Exception e) {
            log.info("该附件【{}】文件命名不符合条件,无法导入", fileName);
        } finally {
            return pan;
        }
    }

    /**
     * 获取附件
     * 只获取附件里的
     * 邮件内容里的附件(图片等)忽略
     *
     * @param part 邮件中多个组合体中的其中一个组合体
     * @param list 附件容器
     * @throws UnsupportedEncodingException
     * @throws MessagingException
     * @throws FileNotFoundException
     * @throws IOException
     */
    public void getAttachment(Part part, List<MailAttachment> list) throws UnsupportedEncodingException, MessagingException,
            FileNotFoundException, IOException {
        if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();    //复杂体邮件
            //复杂体邮件包含多个邮件体
            int partCount = multipart.getCount();
            for (int i = 0; i < partCount; i++) {
                //获得复杂体邮件中其中一个邮件体
                BodyPart bodyPart = multipart.getBodyPart(i);
                //某一个邮件体也有可能是由多个邮件体组成的复杂体
                String disposition = bodyPart.getDisposition();
                if (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {
                    InputStream is = bodyPart.getInputStream();
                    // 附件名通过MimeUtility解码,否则是乱码
                    String name = MimeUtility.decodeText(bodyPart.getFileName());
                    list.add(new MailAttachment(name, is));

                } else if (bodyPart.isMimeType("multipart/*")) {
                    log.info("子邮件里面的附件");
                    getAttachment(bodyPart, list);
                } else {
                    String contentType = bodyPart.getContentType();
                    if (contentType.contains("name") || contentType.contains("application")) {

                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            getAttachment((Part) part.getContent(), list);
        }

    }


    /**
     * @param
     * @param part
     * @return java.io.InputStream
     * @author FeianLing
     * @date 2019/8/20
     * @desc 获取文件输入流
     */
    private void getFileInputStream(Part part, Map<String, InputStream> inputStreamMap) throws Exception {
        String fileName;
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))) {
                    fileName = mPart.getFileName();
                    if (fileName.toLowerCase().indexOf("gb2312") != -1) {
                        fileName = MimeUtility.decodeText(fileName);
                    }
                    if (checkFileName(fileName)) {
                        inputStreamMap.put(fileName, mPart.getInputStream());
                    }
                } else if (mPart.isMimeType("multipart/*")) {
                    log.info("子邮件里面的附件");
                    getFileInputStream(mPart, inputStreamMap);
                } else {
                    fileName = mPart.getFileName();
                    if ((fileName != null)
                            && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
                        fileName = MimeUtility.decodeText(fileName);
                        if (checkFileName(fileName)) {
                            inputStreamMap.put(fileName, mPart.getInputStream());
                        }
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            getFileInputStream((Part) part.getContent(), inputStreamMap);
        }
    }

    /**
     * 获得邮件文本内容
     *
     * @param part        邮件体
     * @param textContent 存储邮件文本内容的字符串
     * @param htmlContent 存储邮件html内容的字符串
     * @throws MessagingException
     * @throws IOException
     */
    public void getMailTextContent(Part part, StringBuffer textContent, StringBuffer htmlContent) throws MessagingException, IOException {
        //如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
        boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
        if (part.isMimeType("text/*") && !isContainTextAttach) {
            String contentType = part.getContentType();
            if (contentType.startsWith("TEXT/PLAIN") || contentType.startsWith("text/plain")) {
                textContent.append(part.getContent().toString());
            }
            if (contentType.startsWith("TEXT/HTML") || contentType.startsWith("text/html")) {
                htmlContent.append(part.getContent().toString());
            }
        } else if (part.isMimeType("message/rfc822")) {
            getMailTextContent((Part) part.getContent(), textContent, htmlContent);
        } else if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();
            int partCount = multipart.getCount();
            for (int i = 0; i < partCount; i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);
                getMailTextContent(bodyPart, textContent, htmlContent);
            }
        }
    }

    /***
     * 获取邮件主题
     * @param message
     * @return
     * @throws MessagingException
     */
    public String getSubject(Message message) throws MessagingException {
        return message.getSubject();
    }

    /**
     * 通过pop3协议获取邮件信息
     * pop3协议下只能通过sentDate来查询
     * receivedDate都为null
     *
     * @return Message[]
     * @throws MessagingException
     */
    public Message[] getPopMessages(String user, String password) throws MessagingException {
        Properties props = new Properties();
        props.setProperty("mail.imapStore.protocol", "pop3");       // 使用pop3协议
        props.setProperty("mail.pop3.port", "110");           // 端口
        props.setProperty("mail.pop3.host", RECEIVE_POP_HOST);       // pop3服务器
        Session session = Session.getInstance(props);
        pop3Store = (POP3Store) session.getStore("pop3");
        pop3Store.connect(RECEIVE_POP_HOST, RECEIVE_POP_PORT, user, password);

        // 获得收件箱
        pop3Folder = (POP3Folder) pop3Store.getFolder("INBOX");
        /* Folder.READ_ONLY:只读权限
         * Folder.READ_WRITE:可读可写(可以修改邮件的状态)
         */
        pop3Folder.open(Folder.READ_WRITE); //打开收件箱
        // 获取前一天的邮件信息
        SearchTerm endTerm = new SentDateTerm(ComparisonTerm.LE, new Date(System.currentTimeMillis()));
        SearchTerm startTerm = new SentDateTerm(ComparisonTerm.GE, new Date(System.currentTimeMillis() - time * 60 * 1000L));
        SearchTerm searchTerm = new AndTerm(startTerm, endTerm);
        //获取附件小于20M的邮件
        int mailSize = 1024 * 1024 * 20;
        SearchTerm intComparisonTerm = new SizeTerm(IntegerComparisonTerm.LT, mailSize);
        Message[] messages = pop3Folder.search(intComparisonTerm);

//         得到收件箱中的所有邮件,并解析
        return pop3Folder.search(searchTerm, messages);
    }


    /**
     * @param
     * @param msg
     * @return java.lang.String
     * @author FeianLing
     * @date 2019/8/20
     * @desc 获取发送地址
     */
    public String getFrom(Message msg) throws MessagingException {
        String from = "";
        InternetAddress[] addresses = (InternetAddress[]) msg.getFrom();
        if (null == addresses || addresses.length == 0) {
            log.error("无法获取发送人地址信息!");
            return from;
        }
        Address address = addresses[0];
        log.info("发件人地址json:" + JSONObject.toJSONString(address));
        String form = ((InternetAddress) address).getAddress();
        return form;
    }

    /**
     * 关闭folder和store资源
     *
     * @throws MessagingException
     */
    public void close() throws MessagingException {
        if (imapFolder != null) {
            imapFolder.close(false);
        }
        if (imapStore != null) {
            imapStore.close();
        }
        if (pop3Folder != null) {
            pop3Folder.close(false);
        }
        if (pop3Store != null) {
            pop3Store.close();
        }
    }

    /**
     * @param
     * @param fileName
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 检查文件名称是否符合要求 FTK-88584316 FTK-申请号.pdf
     */
    private boolean checkFileName(String fileName) {
        return true;
    }

    /**
     * @param
     * @param part
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 判断邮件是否包含附件,如果没有包含附件,返回false 反之返回true
     */
    public boolean isContainAttach(Part part) throws Exception {
        boolean attachFlag = false;
        // String contentType = part.getContentType();
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            for (int i = 0; i < mp.getCount(); i++) {
                BodyPart mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                if ((disposition != null)
                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
                        .equals(Part.INLINE)))) {
                    attachFlag = true;
                } else if (mPart.isMimeType("multipart/*")) {
                    attachFlag = isContainAttach((Part) mPart);
                } else {
                    String conType = mPart.getContentType();

                    if (conType.toLowerCase().indexOf("application") != -1) {
                        attachFlag = true;
                    }
                    if (conType.toLowerCase().indexOf("name") != -1) {
                        attachFlag = true;
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            attachFlag = isContainAttach((Part) part.getContent());
        }
        return attachFlag;
    }


    /**
     * @param
     * @param msg
     * @return boolean
     * @author FeianLing
     * @date 2019/8/20
     * @desc 判断邮件是否是新的邮件
     */
    private boolean isNew(Message msg) throws MessagingException {
        boolean isNewFlag = false;
        Flags flags = msg.getFlags();
        Flags.Flag[] flagsArr = flags.getSystemFlags();
        log.info("邮件状态:" + JSONObject.toJSONString(flagsArr));
        for (Flags.Flag flag : flagsArr) {
            if (flag == Flags.Flag.SEEN) {
                isNewFlag = true;
                log.info("当前邮件为未读状态!");
                break;
            }
        }
        return isNewFlag;
    }

}

邮件附件实体类


import java.io.InputStream;

/**
 * @author jiangyw
 * @date 2019/1/10 21:14
 *
 * 邮件附件类
 */
public class MailAttachment {
    private String name;
    private InputStream inputStream;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public InputStream getInputStream() {
        return inputStream;
    }

    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    public MailAttachment(String name, InputStream inputStream) {
        this.name = name;
        this.inputStream = inputStream;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值