【java】邮件、附件邮件、html邮件发送、未读邮件处理

本文中的代码提供功能如下

1.发送普通邮件

2.发送带附件邮件

3.发送html邮件

4.处理未读邮件

添加依赖

        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>     

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

配置类

@Configuration
@ConfigurationProperties(prefix = "email.config")
@Data
public class EmailConfig {

    private String user;

    private String password;

    private String mailServerHost;



}

配置文件

email:
  config:
    user: 
    password:
    mailServerHost:

以上配置文件须填写对应的配置,与配置类字段对应。

相关实体封装

查询邮件信息实体

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MailInfo {

    private String subject;

    private String from;

    private String receiveAddress;

    private Date sentDate;

    private boolean isSeen;

    private String priority;

    private boolean isReplySign;

    private int size;

    private String msgId;


}

邮件信息实体构建类

public class MailInfoPackagingBuilder {

    public MimeMessage msg;

    public MailInfoPackagingBuilder(MimeMessage msg) {
        this.msg = msg;
    }

    public MailInfo buildMailInfo() throws MessagingException, UnsupportedEncodingException {

        return MailInfo
                .builder()
                .subject(getSubject())
                .from(getFrom())
                .receiveAddress(getReceiveAddress())
                .sentDate(getSentDate())
                .isSeen(isSeen())
                .priority(getPriority())
                .isReplySign(isReplySign())
                .size(msg.getSize())
                .msgId(this.msg.getMessageID())
                .build();
    }


    /**
     * 获得邮件主题
     *
     * @param msg 邮件内容
     * @return 解码后的邮件主题
     */
    private String getSubject() throws UnsupportedEncodingException, MessagingException {
        return MimeUtility.decodeText(this.msg.getSubject());
    }

    /**
     * 获得邮件发件人
     *
     * @param msg 邮件内容
     * @return 姓名 <Email地址>
     * @throws MessagingException
     * @throws UnsupportedEncodingException
     */
    private String getFrom() throws MessagingException, UnsupportedEncodingException {
        String from = "";
        Address[] froms = this.msg.getFrom();
        if (froms.length < 1)
            throw new MessagingException("没有发件人!");

        InternetAddress address = (InternetAddress) froms[0];
        String person = address.getPersonal();
        if (person != null) {
            person = MimeUtility.decodeText(person) + " ";
        } else {
            person = "";
        }
        from = person + "<" + address.getAddress() + ">";

        return from;
    }

    /**
     * 根据收件人类型,获取邮件收件人、抄送和密送地址。如果收件人类型为空,则获得所有的收件人
     * <p>Message.RecipientType.TO  收件人</p>
     * <p>Message.RecipientType.CC  抄送</p>
     * <p>Message.RecipientType.BCC 密送</p>
     *
     * @param msg  邮件内容
     * @param type 收件人类型
     * @return 收件人1 <邮件地址1>, 收件人2 <邮件地址2>, ...
     * @throws MessagingException
     */
    private String getReceiveAddress() throws MessagingException {
        StringBuffer receiveAddress = new StringBuffer();
        Address[] addresss = msg.getAllRecipients();


        if (addresss == null || addresss.length < 1)
            throw new MessagingException("没有收件人!");
        for (Address address : addresss) {
            InternetAddress internetAddress = (InternetAddress) address;
            receiveAddress.append(internetAddress.toUnicodeString()).append(",");
        }

        receiveAddress.deleteCharAt(receiveAddress.length() - 1); //删除最后一个逗号

        return receiveAddress.toString();
    }

    /**
     * 获得邮件发送时间
     *
     * @param msg 邮件内容
     * @return yyyy年mm月dd日 星期X HH:mm
     * @throws MessagingException
     */
    private Date getSentDate() throws MessagingException {
        return msg.getSentDate();

    }

    /**
     * 判断邮件中是否包含附件
     *
     * @return 邮件中存在附件返回true,不存在返回false
     * @throws MessagingException
     * @throws IOException
     */
    private boolean isContainAttachment(Part part) throws MessagingException, IOException {
        boolean flag = false;
        if (part.isMimeType("multipart/*")) {
            MimeMultipart multipart = (MimeMultipart) part.getContent();
            int partCount = multipart.getCount();
            for (int i = 0; i < partCount; i++) {
                BodyPart bodyPart = multipart.getBodyPart(i);
                String disp = bodyPart.getDisposition();
                if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) {
                    flag = true;
                } else if (bodyPart.isMimeType("multipart/*")) {
                    flag = isContainAttachment(bodyPart);
                } else {
                    String contentType = bodyPart.getContentType();
                    if (contentType.indexOf("application") != -1) {
                        flag = true;
                    }

                    if (contentType.indexOf("name") != -1) {
                        flag = true;
                    }
                }

                if (flag) break;
            }
        } else if (part.isMimeType("message/rfc822")) {
            flag = isContainAttachment((Part) part.getContent());
        }
        return flag;
    }

    /**
     * 判断邮件是否已读
     *
     * @param msg 邮件内容
     * @return 如果邮件已读返回true, 否则返回false
     * @throws MessagingException
     */
    private boolean isSeen() throws MessagingException {
        return msg.getFlags().contains(Flags.Flag.SEEN);
    }

    /**
     * 判断邮件是否需要阅读回执
     *
     * @param msg 邮件内容
     * @return 需要回执返回true, 否则返回false
     * @throws MessagingException
     */
    private boolean isReplySign() throws MessagingException {
        boolean replySign = false;
        String[] headers = msg.getHeader("Disposition-Notification-To");
        if (headers != null)
            replySign = true;
        return replySign;
    }

    /**
     * 获得邮件的优先级
     *
     * @param msg 邮件内容
     * @return 1(High):紧急  3:普通(Normal)  5:低(Low)
     * @throws MessagingException
     */
    private String getPriority() throws MessagingException {
        String priority = "普通";
        String[] headers = msg.getHeader("X-Priority");
        if (headers != null) {
            String headerPriority = headers[0];
            if (headerPriority.indexOf("1") != -1 || headerPriority.indexOf("High") != -1)
                priority = "紧急";
            else if (headerPriority.indexOf("5") != -1 || headerPriority.indexOf("Low") != -1)
                priority = "低";
            else
                priority = "普通";
        }
        return priority;
    }

    /**
     * 获得邮件文本内容
     *
     * @param part    邮件体
     * @param content 存储邮件文本内容的字符串
     * @throws MessagingException
     * @throws IOException
     */
    private void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {
        //如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
        boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
        if (part.isMimeType("text/*") && !isContainTextAttach) {
            content.append(part.getContent().toString());
        } else if (part.isMimeType("message/rfc822")) {
            getMailTextContent((Part) part.getContent(), content);
        } 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, content);
            }
        }
    }


    /**
     * 文本解码
     *
     * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本
     * @return 解码后的文本
     * @throws UnsupportedEncodingException
     */
    private String decodeText(String encodeText) throws UnsupportedEncodingException {
        if (encodeText == null || "".equals(encodeText)) {
            return "";
        } else {
            return MimeUtility.decodeText(encodeText);
        }
    }
}

附件文件传递实体

@Data
@AllArgsConstructor
public class MultipartFileDto {

    private byte[]bytes;

    private String type;

    private String filename;
}

邮件发送工具类

@Component
public class EmailHelper {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private EmailConfig emailConfig;

    private static final Properties RECEIVE_PROPS = System.getProperties();
    private static final Properties SEND_PROPS = System.getProperties();

    static {
        RECEIVE_PROPS.setProperty("mail.imap.auth", "true");
        RECEIVE_PROPS.setProperty("mail.store.protocol", "imap");
        RECEIVE_PROPS.setProperty("mail.imap.ssl.enable", "true");
        RECEIVE_PROPS.setProperty("mail.imap.auth.login.disable", "true");
        RECEIVE_PROPS.setProperty("mail.imap.usesocketchannels", "true");
    }

    static {
        SEND_PROPS.setProperty("mail.host", "smtp.exmail.qq.com");
        SEND_PROPS.setProperty("mail.transport.protocol", "smtp");
        SEND_PROPS.setProperty("mail.smtp.auth", "true");
        SEND_PROPS.setProperty("mail.smtp.ssl.enable", "true");
    }

    /**
     * 发送邮件,附件可选
     * @param subject
     * @param text
     * @param addressStr
     * @param multipartFileDtos
     * @throws MessagingException
     */
    public void sendEmail( String subject,String text, List<String> addressStr,MultipartFileDto ... multipartFileDtos) throws MessagingException {

        List<Address>addressList=new ArrayList<>();
        for (String s : addressStr) {
            Address address=new InternetAddress(s);
            addressList.add(address);
        }

        Address[] addresses = addressList.toArray(new Address[0]);

        this.sendEmail(subject,text, addresses,multipartFileDtos);
    }

    /**
     * 发送网页邮件,附件可选
     * @param subject
     * @param html
     * @param addressStr
     * @param multipartFileDtos
     * @throws MessagingException
     */
    public void sendHtmlEmail(String subject, String html, List<String> addressStr, MultipartFileDto ... multipartFileDtos) throws MessagingException {

        List<Address>addressList=new ArrayList<>();
        for (String s : addressStr) {
            Address address=new InternetAddress(s);
            addressList.add(address);
        }

        Address[] addresses = addressList.toArray(new Address[0]);

        this.sendHtmlEmail(subject, html, addresses,multipartFileDtos);
    }

    public void sendHtmlEmail(String subject, String html, Address[] addresses, MultipartFileDto ... multipartFileDtos) throws MessagingException {


        Session session=Session.getInstance(SEND_PROPS);
        //
        Transport transport = session.getTransport();
        transport.connect("smtp.exmail.qq.com", 465, emailConfig.getUser(), emailConfig.getPassword());
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(emailConfig.getUser()));


        message.setRecipients(Message.RecipientType.TO,addresses);
        message.setSubject(subject);

// Create the message part
        BodyPart messageBodyPart = new MimeBodyPart();

// Fill the message
        messageBodyPart.setContent(html,"text/html;charset=UTF-8");

        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(messageBodyPart);

// Part two is attachment
        for (MultipartFileDto multipartFileDto : multipartFileDtos) {
            messageBodyPart = new MimeBodyPart();
            DataSource source = new ByteArrayDataSource(multipartFileDto.getBytes(),multipartFileDto.getType());
            messageBodyPart.setDataHandler(new DataHandler(source));
            messageBodyPart.setFileName(multipartFileDto.getFilename());
            multipart.addBodyPart(messageBodyPart);
        }

// Put parts in message
        message.setContent(multipart);

        message.saveChanges();

// Send the message
        transport.sendMessage(message,message.getAllRecipients());
    }

    /***
     * 发送邮件功能
     */
    public void sendEmail( String subject,String text, Address[] addresses,MultipartFileDto ... multipartFileDtos) throws MessagingException {


        Session session=Session.getInstance(SEND_PROPS);
        //
        Transport transport = session.getTransport();
        transport.connect("smtp.exmail.qq.com", 465, emailConfig.getUser(), emailConfig.getPassword());
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(emailConfig.getUser()));


        message.setRecipients(Message.RecipientType.TO,addresses);
        message.setSubject(subject);

// Create the message part
        BodyPart messageBodyPart = new MimeBodyPart();

// Fill the message
        messageBodyPart.setText(text);

        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(messageBodyPart);

// Part two is attachment
        for (MultipartFileDto multipartFileDto : multipartFileDtos) {
            messageBodyPart = new MimeBodyPart();
            DataSource source = new ByteArrayDataSource(multipartFileDto.getBytes(),multipartFileDto.getType());
            messageBodyPart.setDataHandler(new DataHandler(source));
            messageBodyPart.setFileName(multipartFileDto.getFilename());
            multipart.addBodyPart(messageBodyPart);
        }

// Put parts in message
        message.setContent(multipart);

        message.saveChanges();

// Send the message
        transport.sendMessage(message,message.getAllRecipients());
    }

    /**
     * 查询所有未读邮件
     *
     * @return
     * @throws Exception
     */
    public List<MailInfo> check() throws Exception {

        List<MailInfo> result = new ArrayList<>();

        Store store = this.initStore();

        Folder folder = store.getFolder("inbox");
        folder.open(Folder.READ_ONLY);

        FlagTerm flagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);

        Message[] messages = folder.search(flagTerm);

        for (int i = 0; i < messages.length; i++) {
            MimeMessage msg = (MimeMessage) messages[i];

            MailInfoPackagingBuilder mailInfoPackagingBuilder = new MailInfoPackagingBuilder(msg);

            MailInfo mailInfo = mailInfoPackagingBuilder.buildMailInfo();
            result.add(mailInfo);

        }

        folder.close(false);
        store.close();

        return result;
    }

    public void seenByMessageIds(Set<String> msgIds) throws MessagingException {
        if (CollectionUtils.isEmpty(msgIds)) {
            return;
        }
        Store store = this.initStore();

        Folder folder = store.getFolder("inbox");
        folder.open(Folder.READ_WRITE);

        FlagTerm flagTerm = new FlagTerm(new Flags(Flags.Flag.SEEN), false);

        Message[] messages = folder.search(flagTerm);
        logger.info("本次获取邮件共{}封", messages.length);

        for (int i = 0; i < messages.length; i++) {
            MimeMessage msg = (MimeMessage) messages[i];

            //设置当前邮件状态为已读
            if (msgIds.contains(msg.getMessageID())) {
                logger.info("msgid seen,msgid:{}", msg.getMessageID());
                msg.setFlag(Flags.Flag.SEEN, true);
            }

        }

        folder.close(false);
        store.close();

    }


    private Session initSession() throws MessagingException {
        Session session=Session.getInstance(RECEIVE_PROPS);
        return session;

    }
    private Store initStore() throws MessagingException {
        Session session = this.initSession();
        Store store = session.getStore("imap");
        store.connect(emailConfig.getMailServerHost(), 993, emailConfig.getUser(), emailConfig.getPassword());
        return store;
    }
}

完整代码

 完整的代码示例地址在gitee,地址如下,觉得不错的麻烦给个star

        toolSet: 一些开发中用过的轮子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值