Java 發送郵件實現(JavaMail 和 Spring 實現)

Java 實現郵件的發送,使用 JavaMail 和 Spring 實現html

1、使用 JavaMail

JavaMail 是 Java 處理電子郵件相關的編程接口,可是沒有被加在標準的Java開發工具包中(Java Development Kit),因此咱們使用 JavaMail 須要另外下載依賴包
javax.mail.jar包實現了 SMTP、IMAP 和 POP3 協議java

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>

一、發送一個簡單郵件

下面是用 qq 郵箱發送一個簡單的純文本郵件的例子web

public class SentSimpleMail {

    private static final String MAIL_HOST = "smtp.qq.com"; // 發送郵件的主機
    private static final String FROM = "827952316@qq.com"; // 發件人郵箱地址

    /**
     * 用qq郵箱發送一個簡單郵件
     * 
     * @param subject
     * @param text
     * @param toRecipients 接收郵件,逗號分隔
     * @throws AddressException
     * @throws MessagingException
     */
    public void sentSimpleMail(String subject, String text, String toRecipients)
        throws AddressException, MessagingException {
        /*
         * 初始化JavaMail會話
         */
        Properties props = System.getProperties(); // 得到系統屬性配置,用於鏈接郵件服務器的參數配置
        props.setProperty("mail.smtp.host", MAIL_HOST); // 發送郵件的主機
        props.setProperty("mail.smtp.auth", "true");

        Session session = Session.getInstance(props, null);// 得到Session對象
        session.setDebug(true); // 設置是否顯示debug信息,true 會在控制檯顯示相關信息

        /*
         * 建立郵件消息,發送郵件
         */
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(FROM));

        // To: 收件人
        // message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toRecipient));
        message.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(toRecipients, false));
        // To: 增長收件人(可選)
        // message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toRecipient);
        // Cc: 抄送(可選)
        // message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(ccRecipient));
        // Bcc: 密送(可選)
        // message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(bccRecipient));

        message.setSubject(subject); // 郵件標題
        message.setText(text); // 郵件內容

        // 簡單發送郵件的方式
        Transport.send(message, FROM, "xxxxxxxxxxx"); // 受權碼
    }

    public static void main(String[] args) throws AddressException, MessagingException {
        new SentSimpleMail().sentSimpleMail("標題", "郵件內容", "827952316@qq.com");
    }
}

受權spring

若是須要提供用戶名和密碼給e-mail服務器來達到用戶認證的目的,須要另外添加受權信息編程

props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.user", "${user}");
props.setProperty("mail.password", "${password}");

或者在發送的時候加上用戶和受權碼,如服務器

Transport.send(message, FROM, "xxxxxxxxxxx"); // 受權碼

如在使用 qq 郵箱發送郵件須要獲取受權碼,在郵箱的「設置-帳戶」中設置 session

二、發送基於 HTML 內容的郵件

發送郵件的內容爲 HTML 時,須要把 Mimemessage 的 ContentType 設爲 "text/html"框架

message.setDataHandler(new DataHandler( new ByteArrayDataSource("<h1>This is html message</h1>", "text/html")));

或者ide

message.setContent("<h1>This is html message</h1>", "text/html" );

三、帶有附件的郵件

MimeMessage 繼承Message,表示整封郵件
MimeBodyPart 表示郵件的一個MIME消息
MimeMultipart 表示一個由多個MIME消息組合成的組合MIME消息工具

public class SendMail {

    public void sendMail(String subject, String text, String toRecipients)
        throws AddressException, MessagingException, IOException {
        
        String host = "smtp.qq.com"; // 發送郵件的主機
        String from = "827952316@qq.com"; // 發件人郵箱地址
        
        /*
         * 初始化JavaMail會話
         */
        Properties props = System.getProperties(); // 得到系統屬性配置,用於鏈接郵件服務器的參數配置
        props.setProperty("mail.smtp.host", host); // 發送郵件的主機
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.user", from);
        props.setProperty("mail.password", "xxxxxxxxxxxxxx");  //密碼或者受權碼
        
        Session session = Session.getInstance(props, null);// 得到Session對象
        session.setDebug(true); // 設置是否顯示debug信息,true 會在控制檯顯示相關信息

        /*
         * 建立郵件消息,發送郵件
         */
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress(from));
        message.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(toRecipients, false));
        message.setSubject(subject); // 郵件標題
        
        //建立多重消息
        MimeMultipart mp = new MimeMultipart();
        
        // 文本部分
        MimeBodyPart textPart = new MimeBodyPart();
        textPart.setText(text);
        
        // 附件部分
        MimeBodyPart filePart = new MimeBodyPart();
        filePart.attachFile("D:/0.jpeg");
        filePart.setFileName("0.jpeg");
        
        mp.addBodyPart(textPart);
        mp.addBodyPart(filePart);
        message.setContent(mp);
        
        Transport.send(message);
    }

    public static void main(String[] args) throws AddressException, MessagingException, IOException {
        new SendMail().sendMail("標題", "郵件內容", "827952316@qq.com");
    }
}

2、使用 Spring 發送郵件

在 spring 中,關於郵件(JavaMail)的集成 API 是在 spring-context-supprot 中的 org.springframework.mail 包中,須要 JavaMail 的類庫支持。

在項目中,郵件功能多是一個橫切關注點,極可能爲 AOP 的一個切面

MailSender 是發送電子郵件的核心接口。SimpleMailMessage 類封裝了簡單的郵件屬性(例如from和to)的簡單值

一、基本用法

1)MailSender 和 SimpleMailMessage 的用法

使用 MailSender 和 SimpleMailMessage 來發送郵件

@Component
public class SendMailManagerImpl implements SendMailManager {

    @Autowired
    private MailSender mailSender;
    @Autowired
    private SimpleMailMessage templateMessage;

    @Override
    public void sendMail(String[] to) {
        // SimpleMailMessage 
        SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
        msg.setTo(to);//接收人
        msg.setText("郵件內容");  //這裏的郵件內容是 文本類型
        // msg.setCc(cc);// 抄送
        // msg.setBcc(bcc);// 密送
        // msg.setReplyTo(replyTo);// 回覆
        // msg.setSentDate(new Date());// 發送時間
        // msg.setSubject(subject);// 主題
        // msg.setFrom(from);// 發送人
        try{
            this.mailSender.send(msg);
        }
        catch (MailException ex) {
            System.out.println(ex.getMessage());
        }
    }
}

咱們在 xml 中配置 MailSender 和 模板消息

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.qq.com" />
    <!-- 若是須要帳號密碼受權 -->
    <property name="username" value="827952316@qq.com"/>
    <property name="password" value="xxxxxxxxxxxxxxxx"/>
</bean>
    
<!-- 能夠作一個模板,把郵件的通用內容放到這裏 -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
    <property name="from" value="827952316@qq.com" />
    <property name="subject" value="統一標題" />
</bean>

2)使用 JavaMailSender 和 MimeMessagePreparator

上面的例子是利用了 spring 所封裝的 SimpleMailMessage 類。不過 Spring 框架的郵件支持也附帶了標準 JavaMail 實現,JavaMailSender 類可使用 JavaMail 的 MimeMessage 類

@Component
public class SendMailManagerImpl2 implements SendMailManager {

    @Autowired
    private JavaMailSender mailSender;

    public void sendMail(String[] to) {

        MimeMessagePreparator preparator = (MimeMessage mimeMessage) -> {
            Arrays.asList(to).stream().forEach(x -> {
                try {
                    mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(x));
                } catch (MessagingException e) {
                     System.err.println(e.getMessage());
                }
            });
            mimeMessage.setFrom(new InternetAddress("827952316@qq.com"));
            mimeMessage.setText("郵件內容");
        };
        try {
            this.mailSender.send(preparator);
        }
        catch (MailException ex) {
            System.err.println(ex.getMessage());
        }
    }
}

二、使用 MimeMessageHelper 處理 JavaMail 消息

使用 MimeMessageHelper 能夠很方便的建立處理 JavaMail 的 MimeMessage 對象

JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("smtp.qq.com");

MimeMessage message = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo("test@qq.com");
helper.setText("郵件內容");

sender.send(message);

當咱們想要郵件有附件和內聯資源的時候,使用 MimeMessageHelper 就很方便了

1)發送帶有附件和內聯資源的郵件

咱們發送郵件一般會須要有附件或者是內聯資源(好比,內嵌的圖片),在建立這些至關複雜的郵件,SimpleMailMessage 就很差用了,使用 MimeMessageHelper 幫咱們建立 MimeMessage 對象

@Component
public class SendMailManagerImpl3 implements SendMailManager {

    @Autowired
    private JavaMailSender mailSender;

    public void sendMail(String[] to) {

        MimeMessage message = mailSender.createMimeMessage();
        try {
            // 使用 true 表示要建立一個有多部分的郵件
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
            helper.setFrom("827952316@qq.com");
            helper.setTo(to);
            // 使用 true 表示郵件內容爲 HTML,在這裏引用內聯資源 圖片
            helper.setText("<html><body><h1>郵件內容</h1><img src='cid:inlineImg'/></body></html>", true);

            // 添加附件
            FileSystemResource file = new FileSystemResource(new File("D:/0.jpeg"));
            helper.addAttachment("CoolImage.jpeg", file);

            // 添加內聯資源(在html中引用)
            FileSystemResource res = new FileSystemResource(new File("D:/0.jpeg"));

            helper.addInline("inlineImg", res);

            this.mailSender.send(message);
        } catch (MailException | MessagingException ex) {
            System.err.println(ex.getMessage());
        }
    }
}

使用內聯資源的時候要指定 Content-ID,MimeMessage在郵件內容中添加。添加文本和資源的順序很是重要。要先添加文本,而後再添加資源

三、使用模板建立郵件

一般咱們在使用代碼建立郵件是都不會是簡單的純文本郵件,在使用Java代碼建立基於HTML的電子郵件內容很是繁瑣且容易出錯,並且更改電子郵件內容的顯示結構須要編寫Java代碼,從新編譯,從新部署

使用模板是能夠解決這些問題的,使用模板庫(例如FreeMarker、Velocity、Thymeleaf)來定義電子郵件內容的顯示結構。從 Spring 4.3 以後,Velocity支持已被棄用。這裏咱們使用 FreeMaker 模板發送郵件作個例子

首先咱們添加依賴

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.28</version>
</dependency>

1)配置 bean

FreeMarker 配置

<!-- web項目中 -->
<!-- <bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="templateLoaderPath" value="/WEB-INF/config/template/" />
    <property name="freemarkerSettings">
        <props>
            <prop key="template_update_delay">1800</prop>模板更新延時
            <prop key="default_encoding">UTF-8</prop>
            <prop key="locale">zh_CN</prop>
        </props>
    </property>
</bean> -->
<!-- 非web -->
<bean id="freeMarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
    <property name="templateLoaderPath" value="classpath:template/ftl/" />
</bean>

2)經過模板得到郵件內容

FreeMarker 模板 user.ftl

<html>
    <body>
        <h3>username: ${user.username}</h3>
        <p>password : ${user.password}</p>
        <span>Sent using FreeMarker Template</span>
    </body>
</html>

使用 FreeMarker 模板得到郵件內容

@Component
public class TemplateManagerImpl implements SendMailManager {

    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private Configuration freeMarkerConfiguration;

    @Override
    public void sendMail(String[] to,User user) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            // 使用 true 表示要建立一個有多部分的郵件
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
            helper.setFrom("827952316@qq.com");
            helper.setTo(to);
            helper.setSubject("標題");
            
            //獲取模板
            Map<String, Object> model = new HashMap<String, Object>();
            model.put("user", user);
            String text = geFreeMarkerTemplateContent(model);
            // 使用 true 表示郵件內容爲 HTML
            helper.setText(text, true);

            this.mailSender.send(message);
        } catch (MailException | MessagingException ex) {
            System.err.println(ex.getMessage());
        }
    }

    /**
     * 得到模板內容
     * @param model
     * @return
     */
    private String geFreeMarkerTemplateContent(Map<String, Object> model) {
        String content = null;
        try {
            content = FreeMarkerTemplateUtils.processTemplateIntoString(freeMarkerConfiguration.getTemplate("user.ftl"), model);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        return content;
    }
}

郵件以下

相關文章
相關標籤/搜索