Spring发送邮件模块的用法

时间:2021-09-23 16:44:22

环境准备

Spring的邮件模块底层依赖于JavaMail,它主要目的是为应用提供一个便捷有用的发邮件工具包。邮件模块的代码在spring-context-support的jar包里,所在的package为org.springframework.mail。

Maven的pom.xm需要添加javax.mail jar包的依赖

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

如果spring环境里没有加入spring-context-support,也需要添加到依赖里。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>

核心接口和类

在org.springframework.mail package下有几个核心的接口:

  • MailSender:发邮件的核心接口
  • MailMessage:表示邮件模型的接口,包含to,from等等,Spring提供里一个SimpleMailMessage类实现此接口,用于发送简单的邮件内容。
  • JavaMailSender:使用JavaMail相关类的发送邮件类。其默认实现类为JavaMailSenderImpl
  • MailException:邮件异常的*类

使用MailSender和SimpleMailMessage发送简单的邮件

public class MailSenderService {

    private MailSender mailSender;
    private SimpleMailMessage templateMessage;

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

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

    public void sendSimpleMail(String to,String mailContent) {
        SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);  //接收模板信息
        msg.setTo(to);
        msg.setText(mainContent);
        try{
            this.mailSender.send(msg);
        } catch (MailException ex) {
            System.err.println(ex.getMessage());
        }
    }

}

xml配置

<bean  class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="${mail.host}"/>
    <property name="username" value="${mail.username}"></property>
    <property name="password" value="${mail.password}"></property>
</bean>

<!-- 配置发邮件的模板,设置了from,主题 -->
<bean  class="org.springframework.mail.SimpleMailMessage">
    <property name="from" value="${mail.from}"/>
    <property name="subject" value="${mail.defaultSubject}"/>
</bean>

<bean  class="com.mycompany.service.MailSenderService ">
    <property name="mailSender" ref="mailSender"/>
    <property name="templateMessage" ref="templateMessage"/>
</bean>

使用JavaMailSender和MimeMessagePreparator发送邮件

使用MailSender和SimpleMailMessage只能文本这些简单的邮件,如果需要发送html或者添加附件,我们需要使用JavaMail的相关接口和类。Spring邮件模块提供JavaMailSender和MimeMessagePreparator两个类,它们暴露了JavaMail的MimeMessage用于发送复杂的邮件内容。

public class MailSenderService {

    private JavaMailSender mailSender;

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

    public void sendMail(String from,String to,String mailContent) {
        MimeMessagePreparator preparator = new MimeMessagePreparator() {

            public void prepare(MimeMessage mimeMessage) throws Exception {
                mimeMessage.setRecipient(Message.RecipientType.TO,
                        new InternetAddress(to));
                mimeMessage.setFrom(new InternetAddress(from));
                mimeMessage.setText(text);
            }
        };

        try{
            this.mailSender.send(preparator );
        } catch (MailException ex) {
            System.err.println(ex.getMessage());
        }
    }

}

MimemessagePreparator接口提供了prepare方法用于暴露JavaMail的MimeMessage,这样我们就可以对邮件内容做一些灵活的定制。

使用MimeMessageHelper

如果觉得直接使用JavaMail的MimeMessage设置邮件很麻烦,Spring提供了MimeMessageHelper类来封装对MimeMessage的操作。

上面的例子可以改为:

public class MailSenderService {

    private JavaMailSender mailSender;

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

    public void sendMail(String to,String mailContent) {

        MimeMessage message = sender.createMimeMessage();  //现创建MimeMesssage
        MimeMessageHelper helper = new MimeMessageHelper(message);// 对MimeMessage包装
        helper.setTo(to);
        helper.setText(mailContent);

        try{
            this.mailSender.send(message); //最后发送的还是MimeMessage
        } catch (MailException ex) {
            System.err.println(ex.getMessage());
        }
    }

}

发送附件

使用JavaMail的MimeMessage可以发送丰富的邮件内容,如附件。这里基于MimeMessageHelper实现发送附件(当然,你也可以直接操作MimeMessage发送附件)。

public class MailSenderService {

    private JavaMailSender mailSender;

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

    public void sendMail(String to,String mailContent,File attachment) {

        MimeMessage message = sender.createMimeMessage();  //现创建MimeMesssage
        MimeMessageHelper helper = new MimeMessageHelper(message);// 对MimeMessage包装
        helper.setTo(to);
        helper.setText(mailContent);

        FileSystemResource file = new FileSystemResource(attachment);
        helper.addAttachment(attachment.getName(), file);//添加附件

        try{
            this.mailSender.send(message); //最后发送的还是MimeMessage
        } catch (MailException ex) {
            System.err.println(ex.getMessage());
        }
    }

}

发送html

MimeMessageHelper发送html的设置很简单,如下:

public class MailSenderService {

    private JavaMailSender mailSender;

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

    public void sendHtmlMail(String to,String html) {

        MimeMessage message = sender.createMimeMessage();  //现创建MimeMesssage
        MimeMessageHelper helper = new MimeMessageHelper(message);// 对MimeMessage包装
        helper.setTo(to);
        helper.setText(html,true);  //只要对setText的第二个参数设置为true即可
        try{
            this.mailSender.send(message); //最后发送的还是MimeMessage
        } catch (MailException ex) {
            System.err.println(ex.getMessage());
        }
    }

}

处理乱码

如果发送中文相关内容,你可能会碰到乱码的情况。有几个地方会出现乱码:from,subject和邮件内容

下面以utf8编码为例

  • 内容:在构建MimeMessageHelper设置编码格式,(mimeMessage,"utf8");
  • from:使用MimeMessageHelper的setFrom(InternetAddress)方法,对InternetAddress设置utf8。
  • subject:使用MimeUtility对主题编码,MimeUtility.encodeWord(subject, "UTF-8", "Q")

示例

MimeMessageHelper message = new MimeMessageHelper(mimeMessage,"utf8");
message.setTo(to);
message.setFrom(new InternetAddress(from,personName,"UTF-8"));
message.setSubject(MimeUtility.encodeWord(subject, "UTF-8", "Q"));