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;
    }
}

邮件以下

相关文章
相关标签/搜索