1. 程式人生 > >《Spring 5官方文件》電子郵件

《Spring 5官方文件》電子郵件

原文連結  譯者:lofo

29. 電子郵件

29.1 介紹

依賴庫:使用Spring框架的郵件功能需要將JavaMail的Jar包新增到依賴中。這個庫可以Maven中心找到:com.sun.mail:javax.mail

Spring提供了一個實用的傳送電子郵件庫,它為使用者遮蔽了郵件系統的底層細節和客戶端的底層資源處理。

Spring郵件相關功能在org.springframework.mail包下,其中MailSender是傳送郵件的核心介面;SimpleMailMessage類是對郵件屬性(發件人、收件人以等)進行簡單的封裝。這個包中也包含一系列的檢查異常,它們是對郵件系統低級別的異常進行抽象,且均繼承自MailException

。有關異常的更多資訊,請參閱相關javadoc。

org.springframework.mail.javamail.JavaMailSender介面繼承自MailSender介面,並增加了一些特有的JavaMail功能,如MIME郵件的支援。JavaMailSender還提供了一個用於編寫MIME訊息的回撥org.springframework.mail.javamail.MimeMessagePreparator介面。

29.2 使用

我們假設有一個OrderManager業務介面:

public interface OrderManager {

    void placeOrder(Order order);

}

假設我們需要生成一個有訂單號的郵件,併發送給相關的客戶。

29.2.1 MailSenderSimpleMailMessage的基本用法

import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

public class SimpleOrderManager implements OrderManager {

    private MailSender mailSender;
    private SimpleMailMessage templateMessage;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setTemplateMessage(SimpleMailMessage templateMessage) {
        this.templateMessage = templateMessage;
    }

    public void placeOrder(Order order) {

        // Do the business calculations...

        // Call the collaborators to persist the order...

        // Create a thread safe "copy" of the template message and customize it
        SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
        msg.setTo(order.getCustomer().getEmailAddress());
        msg.setText(
            "Dear " + order.getCustomer().getFirstName()
                + order.getCustomer().getLastName()
                + ", thank you for placing order. Your order number is "
                + order.getOrderNumber());
        try{
            this.mailSender.send(msg);
        }
        catch (MailException ex) {
            // simply log it and go on...
            System.err.println(ex.getMessage());
        }
    }

}

在xml中新增相關的Bean定義:

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="mail.mycompany.com"/>
</bean>

<!-- this is a template message that we can pre-load with default state -->
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
    <property name="from" value="[email protected]"/>
    <property name="subject" value="Your order"/>
</bean>

<bean id="orderManager" class="com.mycompany.businessapp.support.SimpleOrderManager">
    <property name="mailSender" ref="mailSender"/>
    <property name="templateMessage" ref="templateMessage"/>
</bean>

29.2.2 使用JavaMailSenderMimeMessagePreparator

下面的例子是OrderManager介面的另一種實現,其中使用了MimeMessagePreparator類。 在這裡,mailSenderJavaMailSender型別,因此我們可以使用JavaMail MimeMessage類:

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import javax.mail.internet.MimeMessage;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;

public class SimpleOrderManager implements OrderManager {

    private JavaMailSender mailSender;

    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void placeOrder(final Order order) {

        // Do the business calculations...

        // Call the collaborators to persist the order...

        MimeMessagePreparator preparator = new MimeMessagePreparator() {

            public void prepare(MimeMessage mimeMessage) throws Exception {

                mimeMessage.setRecipient(Message.RecipientType.TO,
                        new InternetAddress(order.getCustomer().getEmailAddress()));
                mimeMessage.setFrom(new InternetAddress("[email protected]"));
                mimeMessage.setText(
                        "Dear " + order.getCustomer().getFirstName() + " "
                            + order.getCustomer().getLastName()
                            + ", thank you for placing order. Your order number is "
                            + order.getOrderNumber());
            }
        };

        try {
            this.mailSender.send(preparator);
        }
        catch (MailException ex) {
            // simply log it and go on...
            System.err.println(ex.getMessage());
        }
    }

}

上面中郵件程式碼只是作為示例,最好方式是將郵件傳送程式碼重構到其它Bean中,並在OrderManager合適的地方呼叫它。

Spring框架郵件也支援標準的JavaMail實現。 瞭解更多資訊,請參閱相關的javadocs。

29.2 使用MimeMessageHelper

org.springframework.mail.javamail.MimeMessageHelper是一個處理JavaMail訊息的好工具,它遮蔽了很多JavaMail API的細節,所以使用MimeMessageHelper可以很簡便的建立一個MimeMessage

// of course you would use DI in any real-world cases
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setTo("[email protected]");
helper.setText("Thank you for ordering!");

sender.send(message);

29.3.1 附件和嵌入資源

郵件允許新增附件和內聯資源。嵌入資源是你嵌入到郵件中的圖片或樣式,但又不希望顯示為附件。

附件

下面的例子將展示如何使用MimeMessageHelper傳送一個帶JPEG圖片附件的郵件:

JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();

// use the true flag to indicate you need a multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("[email protected]");

helper.setText("Check out this image!");

// let's attach the infamous windows Sample file (this time copied to c:/)
FileSystemResource file = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addAttachment("CoolImage.jpg", file);

sender.send(message);

嵌入資源

下面的例子將展示如何使用MimeMessageHelper傳送一個嵌入圖片的郵件:

JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost("mail.host.com");

MimeMessage message = sender.createMimeMessage();

// use the true flag to indicate you need a multipart message
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo("[email protected]");

// use the true flag to indicate the text included is HTML
helper.setText("<html><body><img src='cid:identifier1234'></body></html>", true);

// let's include the infamous windows Sample file (this time copied to c:/)
FileSystemResource res = new FileSystemResource(new File("c:/Sample.jpg"));
helper.addInline("identifier1234", res);

sender.send(message);

嵌入資源需要使用Content-ID(上面的例子identifier1234)新增到MIME訊息中。文字和嵌入資源新增是有順序的,需要按照先新增文字,再新增嵌入資源的順序。否則,它將不會工作!

29.3.2 使用模板庫建立電子郵件內容

在前面的例子中,我們通常使用message.setText(..)等方法建立郵件內容。在簡單的情況下,像前面例子那樣使用API就可以滿足我們的需要了。

在典型的企業應用程式中,下面的原因讓你不定會使用上面的方法建立你的郵件內容。

  • 在Java程式碼中建立HTML的電子郵件內容冗長,且容易出錯
  • 呈現邏輯和業務邏輯混雜
  • 更改電子郵件內容的展示結構需要編寫Java程式碼,重新編譯,重新部署…

通常解決方法是使用模板框架定義電子郵件的呈現邏輯,如FreeMarker。分離呈現邏輯和業務邏輯使得你的程式碼更清晰。當你的郵件的內容變的複雜時,這絕對是一個最佳實踐,而且Spring框架對FreeMarker有很好的支援。