美文网首页Spring之路
Spring和Email整合详解

Spring和Email整合详解

作者: 逍遥天扬 | 来源:发表于2019-02-15 18:50 被阅读11次

    Spring和Email整合详解

    官方主页

    Spring Email

    概述

    Spring Mail API都在org.springframework.mail及其子包org.springframework.mail.javamail中封装。

    JavaMailSenderImpl: 邮件发送器,主要提供了邮件发送接口、透明创建Java Mail的MimeMessage、及邮件发送的配置(如:host/port/username/password...)。
    MimeMailMessage、MimeMessageHelper:对MimeMessage进行了封装。Spring还提供了一个回调接口MimeMessagePreparator, 用于准备JavaMail的MIME信件.

    Git地址:
    Gitee

    项目地址:
    品茗IT-Spring之路专题

    品茗IT:提供在线快速构建Spring项目工具。

    开始搭建

    依赖Jar包

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
    

    spring-mail.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
                         http://www.springframework.org/schema/beans
                         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                         http://www.springframework.org/schema/aop
                         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                         http://www.springframework.org/schema/context
                         http://www.springframework.org/schema/context/spring-context-4.0.xsd ">
    
        <bean id="annotationPropertyConfigurerMail"
              class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="order" value="1" />
            <property name="ignoreUnresolvablePlaceholders" value="true" />
            <property name="locations">
                <list>
                    <value>classpath:mail.properties</value>
                </list>
            </property>
        </bean>
    
        <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
            <property name="host" value="${mail.smtpHost}" />
            <property name="port" value="${mail.port}" />
            <property name="username" value="${mail.username}" />
            <property name="password" value="${mail.password}" />
            <property name="defaultEncoding" value="${mail.charset}"></property>
            <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
            </props>
            </property>
        </bean>
        
    </beans>
    

    这里,声明了javaMailSender的bean,配置从mail.properties配置文件中取,spring-mail.xml配置完成后,只需要在spring的配置文件中
    <import resource="classpath*:spring-mail.xml"/>
    即可

    mail.properties配置文件

    mail.smtpHost=smtp.aliyun.com
    mail.charset=utf-8
    mail.fromAddress=xxxx@aliyun.com
    mail.maxAttachSize=10M
    mail.port=25
    mail.username=xxxx@aliyun.com
    mail.password=xxxxx
    mail.smtp.auth=true
    

    发送邮件业务逻辑

    这里,我们对Mail组件进行了扩展,以方便发送多类型的邮件。

    MailServiceImpl:

    package com.cff.springwork.mail.service;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    import javax.mail.MessagingException;
    import javax.mail.internet.MimeMessage;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.mail.SimpleMailMessage;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    import org.springframework.stereotype.Component;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.alibaba.fastjson.parser.Feature;
    import com.cff.springwork.mail.entity.AttachFile;
    import com.cff.springwork.mail.entity.InlineFile;
    import com.cff.springwork.mail.entity.JsonTable;
    import com.cff.springwork.mail.entity.MailMessage;
    import com.cff.springwork.mail.entity.MailType;
    import com.cff.springwork.mail.entity.TextString;
    
    @Component
    public class MailServiceImpl implements MailService {
    
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
        static final String DELIM_STR = "{}";
        @Autowired
        private JavaMailSender mailSender;
    
        @Value("${mail.fromAddress}")
        private String from;
    
        MailMessage mailMessage;
    
        @Override
        public void sendSimpleMail(String to, String subject, String content) {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(to);
            message.setSubject(subject);
            message.setText(content);
    
            try {
                mailSender.send(message);
                logger.info("简单邮件已经发送。");
            } catch (Exception e) {
                logger.error("发送简单邮件时发生异常!", e);
            }
    
        }
    
        @Override
        public void sendHtmlMail(String to, String subject, String content) {
            MimeMessage message = mailSender.createMimeMessage();
    
            try {
                // true表示需要创建一个multipart message
                MimeMessageHelper helper = new MimeMessageHelper(message, true);
                helper.setFrom(from);
                helper.setTo(to);
                helper.setSubject(subject);
                helper.setText(content, true);
    
                mailSender.send(message);
                logger.info("html邮件发送成功");
            } catch (MessagingException e) {
                logger.error("发送html邮件时发生异常!", e);
            }
        }
    
        @Override
        public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId) {
            MimeMessage message = mailSender.createMimeMessage();
    
            try {
                MimeMessageHelper helper = new MimeMessageHelper(message, true);
                helper.setFrom(from);
                helper.setTo(to);
                helper.setSubject(subject);
                helper.setText(content, true);
    
                FileSystemResource res = new FileSystemResource(new File(rscPath));
                helper.addInline(rscId, res);
    
                mailSender.send(message);
                logger.info("嵌入静态资源的邮件已经发送。");
            } catch (MessagingException e) {
                logger.error("发送嵌入静态资源的邮件时发生异常!", e);
            }
        }
    
        public void sendAttachmentsMail(String to, String subject, String content, String filePath) {
            MimeMessage message = mailSender.createMimeMessage();
    
            try {
                MimeMessageHelper helper = new MimeMessageHelper(message, true);
                helper.setFrom(from);
                helper.setTo(to);
                helper.setSubject(subject);
                helper.setText(content, true);
    
                FileSystemResource file = new FileSystemResource(new File(filePath));
                String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
                helper.addAttachment(fileName, file);
    
                mailSender.send(message);
                logger.info("带附件的邮件已经发送。");
            } catch (MessagingException e) {
                logger.error("发送带附件的邮件时发生异常!", e);
            }
        }
    
        public MailMessage getMailMessage() {
            return mailMessage;
        }
    
        public void setMailMessage(MailMessage mailMessage) {
            this.mailMessage = mailMessage;
        }
    
        public void sendHtml(String content, MailType... mailTypes) throws IOException {
            MimeMessage message = mailSender.createMimeMessage();
            try {
                MimeMessageHelper helper = new MimeMessageHelper(message, true);
                helper.setFrom(mailMessage.getFrom());
                helper.setTo(mailMessage.getTo());
                helper.setSubject(mailMessage.getSubject());
                String msg = getContent(content, mailTypes);
                System.out.println(msg);
                helper.setText(msg, true);
                for (MailType item : mailTypes) {
                    switch (item.getType()) {
                    case MailType.TYPE_FILE:
                        InlineFile inlineFile = (InlineFile) item;
                        helper.addInline(inlineFile.getCid(), new File(inlineFile.getFilePath()));
                        break;
                    case MailType.TYPE_ATTACH:
                        AttachFile attachFile = (AttachFile) item;
                        helper.addAttachment(attachFile.getFileName(), new File(attachFile.getFilePath()));
                        break;
                    }
                }
                
    //          mailSender.send(message);
                logger.info("带附件的邮件已经发送。");
            } catch (MessagingException e) {
                logger.error("发送带附件的邮件时发生异常!", e);
            }
        }
    
        public String getContent(String content, MailType... mailTypes)
                throws MessagingException, IOException {
            String bodyPrefix = "<html><body>";
            String bodySuffix = "</body></html>";
            StringBuffer sb = new StringBuffer();
            sb.append(bodyPrefix);
            for (MailType item : mailTypes) {
                if(content.length() < 1)break;
    
                int index = content.indexOf(DELIM_STR);
                if(index == -1)break;
                sb.append(content.substring(0, index));
                switch (item.getType()) {
                case MailType.TYPE_FILE:
                    InlineFile inlineFile = (InlineFile) item;
                    sb.append("<img src=\'cid:" + inlineFile.getCid() + "\' />");
                    break;
                case MailType.TYPE_TEXT:
                    TextString textString = (TextString) item;
                    sb.append(textString.getText());
                    break;
                case MailType.TYPE_JSON:
                    JsonTable json = (JsonTable) item;
                    sb.append(genReportData(json));
                    break;
                }
                content = content.substring(index + 2);
            }
            sb.append(content);
            sb.append(bodySuffix);
            return sb.toString();
        }
        
        private String read(String filePath) throws IOException {
            String encoding = "UTF-8";
            File tmpFile = new File(filePath);
            Long filelength = tmpFile.length();
            byte[] filecontent = new byte[filelength.intValue()];
            FileInputStream in = new FileInputStream(tmpFile);
            in.read(filecontent);
            in.close();
            String fileJson = new String(filecontent, encoding);
            return fileJson;
        }
        
        private String genReportData(JsonTable jsonTable) throws IOException {
            JSONArray ja = (JSONArray) JSON.parse(read(jsonTable.getData()),Feature.OrderedField);
            StringBuilder sb = new StringBuilder();
            try {
                sb.append("<br />\n");
                sb.append("<table border=\"1\" style=\"border-collapse:collapse;font-size:14px\">\n");
                sb.append("<caption align = \"left\">");
                sb.append(jsonTable.getTitle());
                sb.append("</caption>\n");
                JSONObject jsonFirst = (JSONObject) ja.get(0);
                
                sb.append("<tr>\n");
                for(String key : jsonFirst.keySet()){
                    sb.append("<td>");
                    sb.append(jsonFirst.get(key));
                    sb.append("</td>\n");
                }
                
                sb.append("</tr>\n");
                ja.remove(0);
                for (Object column : ja) {
                    sb.append("<tr>\n");
                    JSONObject json = (JSONObject) column;
                    for(String key : jsonFirst.keySet()){
                        sb.append("<td>");
                        sb.append(json.get(key));
                        sb.append("</td>\n");
                    }
                    
                    sb.append("</tr>\n");
                }
    
                sb.append("</table>\n");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return sb.toString();
        }
    }
    

    MailService:

    package com.cff.springwork.mail.service;
    
    import java.io.IOException;
    
    import com.cff.springwork.mail.entity.MailMessage;
    import com.cff.springwork.mail.entity.MailType;
    
    public interface MailService {
    
        void sendSimpleMail(String to, String subject, String content);
    
        void sendHtmlMail(String to, String subject, String content);
    
        void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);
        public void setMailMessage(MailMessage mailMessage);
        
        public void sendHtml(String content, MailType... mailTypes) throws IOException;
    }
    

    多种邮件类型

    我们可以定义MailType抽象类,以适应不同的邮件类型。

    MailType:

    package com.cff.springwork.mail.entity;
    
    public abstract class MailType {
        public final static char TYPE_FILE ='F';
        public final static char TYPE_ATTACH ='A';
        public final static char TYPE_TEXT ='T';
        public final static char TYPE_JSON ='J';
        public abstract char getType();
    }
    

    InlineFile 是内嵌文件类型。

    InlineFile :

    package com.cff.springwork.mail.entity;
    
    public class InlineFile extends MailType{
        private String filePath;
        private String cid;
        @Override
        public char getType() {
            return MailType.TYPE_FILE;
        }
    
        public String getFilePath() {
            return filePath;
        }
    
        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }
    
        public String getCid() {
            return cid;
        }
    
        public void setCid(String cid) {
            this.cid = cid;
        }
        
    }
    

    详细完整代码,可以在Spring组件化构建中选择查看,并下载。

    快速构建项目

    Spring组件化构建

    相关文章

      网友评论

        本文标题:Spring和Email整合详解

        本文链接:https://www.haomeiwen.com/subject/gnbmeqtx.html