47. Spring Boot发送邮件【从零开始学Spring Boot】

Spring提供了非常好用的JavaMailSender接口实现邮件发送。在Spring BootStarter模块中也为此提供了自动化配置。下面通过实例看看如何在Spring Boot中使用JavaMailSender发送邮件。

      

快速入门:

       那么如何进行使用呢?很简单最核心的就两个步骤:

Spring Boot的工程中的pom.xml中引入spring-boot-starter-mail依赖:

<!-- 发送邮件. -->

<dependency> 

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-mail</artifactId>

</dependency> 

 

 

如其他自动化配置模块一样,在完成了依赖引入之后,只需要在application.properties中配置相应的属性内容。

下面我们以QQ邮箱为例,在application.properties中加入如下配置(注意替换自己的用户名和密码):

########################################################

###mail setting

########################################################

设置邮箱主机

spring.mail.host=smtp.qq.com

设置用户名

spring.mail.username=用户名

设置密码

spring.mail.password=密码

设置是否需要认证,如果为true,那么用户名和密码就必须的,

#如果设置false,可以不设置用户名和密码,当然也得看你的对接的平台是否支持无密码进行访问的。

spring.mail.properties.mail.smtp.auth=true

# STARTTLS[1]  是对纯文本通信协议的扩展。它提供一种方式将纯文本连接升级为加密连接(TLSSSL),而不是另外使用一个端口作加密通信。

spring.mail.properties.mail.smtp.starttls.enable=true

spring.mail.properties.mail.smtp.starttls.required=true

 

接下来我们通过单元测试来测试简单邮件的发送:

(如何在spring boot进行单元测试可以参看文章:

       http://412887952-qq-com.iteye.com/blog/2292739

 

package com.kfit;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.SpringApplicationConfiguration;

import org.springframework.mail.SimpleMailMessage;

import org.springframework.mail.javamail.JavaMailSender;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

 

/**

 *

 * @author Angel(QQ:412887952)

 * @version v.0.1

 */

@RunWith(SpringJUnit4ClassRunner.class)

@SpringApplicationConfiguration(classes = App.class)

public class AppTest {

    @Autowired

    private JavaMailSender mailSender;

   

    /**

     * 修改application.properties的用户,才能发送。

     */

    @Test

    public void sendSimpleEmail(){

       SimpleMailMessage message = new SimpleMailMessage();

      

       message.setFrom("412887952@qq.com");//发送者.

       message.setTo("1473773560@qq.com");//接收者.

       message.setSubject("测试邮件(邮件主题)");//邮件主题.

       message.setText("这是邮件内容");//邮件内容.

      

       mailSender.send(message);//发送邮件

    }

}

一个简单的邮件发送就完成了,运行一下该单元测试,看看效果如何?

 

由于Spring Bootstarter模块提供了自动化配置,所以在引入了spring-boot-starter-mail依赖之后,会根据配置文件中的内容去创建JavaMailSender实例,因此我们可以直接在需要使用的地方直接@Autowired来引入邮件发送对象。

 

进阶使用:

       我们通过使用SimpleMailMessage实现了简单的邮件发送,但是实际使用过程中,我们还可能会带上附件、或是使用邮件模块等。这个时候我们就需要使用MimeMessage来设置复杂一些的邮件内容,下面我们就来依次实现一下。

 

发送附件

       发送附件主要通过MimeMessageHelper来进行操作的,实际中也很简单。

 

/**

     * 测试发送附件.(这里发送图片.)

     * @throws MessagingException

     */

    @Test

    public void sendAttachmentsEmail() throws MessagingException{

       //这个是javax.mail.internet.MimeMessage下的,不要搞错了。

       MimeMessage mimeMessage =  mailSender.createMimeMessage();

       MimeMessageHelper helper = new MimeMessageHelper(mimeMessagetrue);

      

       //基本设置.

       helper.setFrom("412887952@qq.com");//发送者.

       helper.setTo("1473773560@qq.com");//接收者.

       helper.setSubject("测试附件(邮件主题)");//邮件主题.

       helper.setText("这是邮件内容(有附件哦.");//邮件内容.

      

       //org.springframework.core.io.FileSystemResource下的:

       //附件1,获取文件对象.

       FileSystemResource file1 = new FileSystemResource(newFile("D:/test/head/head1.jpg"));

       //添加附件,这里第一个参数是在邮件中显示的名称,也可以直接是head.jpg,但是一定要有文件后缀,不然就无法显示图片了。

       helper.addAttachment("头像1.jpg"file1);

       //附件2

       FileSystemResource file2 = new FileSystemResource(newFile("D:/test/head/head2.jpg"));

       helper.addAttachment("头像2.jpg"file2);

       

        mailSender.send(mimeMessage);

    }

 

 

嵌入静态资源:

       除了发送附件之外,我们在邮件内容中可能希望通过嵌入图片等静态资源,让邮件获得更好的阅读体验,而不是从附件中查看具体图片,下面的测试用例演示了如何通过MimeMessageHelper实现在邮件正文中嵌入静态资源。

       内嵌图片,给定一个CID值即可,增加附件,使用MimeMessageHelper的addAttachment即可现在一般不会做内嵌图片,因为这样邮件会很大,容易对服务器造成压力,一般做法是使用图片链接另外,如果要做内嵌或发送图片,你应该使用信用较高的邮箱帐户,否则会报错:554 DT:SPM 发送的邮件内容包含了未被许可的信息,或被系统识别为垃圾邮件。请检查是否有用户发送病毒或者垃圾邮件
对于163邮箱服务器会产生的其他问题,参见:http://help.163.com/09/1224/17/5RAJ4LMH00753VB8.html

 

以下是发送静态资源的核心代码:

/**

     * 邮件中使用静态资源.

     * @throws Exception

     */

    @Test

    public void sendInlineMail() throws Exception {

        MimeMessage mimeMessage = mailSender.createMimeMessage();

 

        MimeMessageHelper helper = new MimeMessageHelper(mimeMessagetrue);

      //基本设置.

       helper.setFrom("412887952@qq.com");//发送者.

       helper.setTo("1473773560@qq.com");//接收者.

       helper.setSubject("测试静态资源(邮件主题)");//邮件主题.

       // 邮件内容,第二个参数指定发送的是HTML格式 

       //说明:嵌入图片<img src='cid:head'/>,其中cid:是固定的写法,而aaa是一个contentId

        helper.setText("<body>这是图片:<img src='cid:head' /></body>"true);

       

        FileSystemResource file = new FileSystemResource(newFile("D:/test/head/head1.jpg"));

        helper.addInline("head",file);

 

        mailSender.send(mimeMessage);

 

    }

这里需要注意的是addInline函数中资源名称head需要与正文中cid:head对应起来

嵌入图片<img src='cid:head'/>,其中cid:是固定的写法,而aaa是一个contentId

 

 

 

 

 

 

 

 

 

模板邮件:

       通常我们使用邮件发送服务的时候,都会有一些固定的场景,比如重置密码、注册确认等,给每个用户发送的内容可能只有小部分是变化的。所以,很多时候我们会使用模板引擎来为各类邮件设置成模板,这样我们只需要在发送时去替换变化部分的参数即可。

       Spring Boot中使用模板引擎来实现模板化的邮件发送也是非常容易的,下面我们以freemarker为例实现一下。

       引入freemarker模块的依赖:

<!-- 引入模板引擎. -->

<dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-freemarker</artifactId>

</dependency>

 

加入配置信息:

########################################################

###FREEMARKER (FreeMarkerAutoConfiguration)

########################################################

spring.freemarker.allow-request-override=false

spring.freemarker.cache=true

spring.freemarker.check-template-location=true

spring.freemarker.charset=UTF-8

spring.freemarker.content-type=text/html

spring.freemarker.expose-request-attributes=false

spring.freemarker.expose-session-attributes=false

spring.freemarker.expose-spring-macro-helpers=false

#spring.freemarker.prefix=

#spring.freemarker.request-context-attribute=

#spring.freemarker.settings.*=

#spring.freemarker.suffix=.ftl

#spring.freemarker.template-loader-path=classpath:/templates/ #comma-separated list

 

resources/templates/下,创建一个模板页面email.ftl

<html> 

<body> 

    <h3>你好, ${username}, 这是一封模板邮件!</h3>

</body> 

</html>

 

最后,我们在单元测试中加入发送模板邮件的测试用例,具体如下:

 

/**

     * 模板邮件;

     * @throws Exception

     */

    @Test

    public void sendTemplateMail() throws Exception {

 

        MimeMessage mimeMessage = mailSender.createMimeMessage();

 

        MimeMessageHelper helper = new MimeMessageHelper(mimeMessagetrue);

        //基本设置.

       helper.setFrom("412887952@qq.com");//发送者.

       helper.setTo("1473773560@qq.com");//接收者.

       helper.setSubject("模板邮件(邮件主题)");//邮件主题.

 

        Map<String, Object> model = new HashMap<String, Object>();

        model.put("username""林峰");

       

         Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);  

        // 设定去哪里读取相应的ftl模板  

        cfg.setClassForTemplateLoading(this.getClass(), "/templates");  

        // 在模板文件目录中寻找名称为name的模板文件  

        Template template   = cfg.getTemplate("email.ftl");

       

        String html = FreeMarkerTemplateUtils.processTemplateIntoString(template,model);

        helper.setText(htmltrue);

 

        mailSender.send(mimeMessage);

    }

 

 

       运行一下,就可以收到内容为你好,林峰,这是一封模板邮件!的邮件。这里,我们通过传入username的参数,在邮件内容中替换了模板中的${username}变量。

 

Spring Boot 系列博客】

54. spring boot日志升级篇—logback【从零开始学Spring Boot】

 

52. spring boot日志升级篇—log4j多环境不同日志级别的控制【从零开始学Spring Boot】 

 

51. spring boot属性文件之多环境配置【从零开始学Spring Boot】

 

50. Spring Boot日志升级篇—log4j【从零开始学Spring Boot】

 

49. spring boot日志升级篇—理论【从零开始学Spring Boot】

 

48. spring boot单元测试restfull API【从零开始学Spring Boot】

 

47. Spring Boot发送邮件【从零开始学Spring Boot】

 

46. Spring Boot中使用AOP统一处理Web请求日志

 

45. Spring Boot MyBatis连接Mysql数据库【从零开始学Spring Boot】

 

44. Spring Boot日志记录SLF4J【从零开始学Spring Boot】

 

43. Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】

 

42. Spring Boot多数据源【从零开始学Spring Boot】

 

41. Spring Boot 使用Java代码创建Bean并注册到Spring中【从零开始学Spring Boot】

 

40. springboot + devtools(热部署)【从零开始学Spring Boot】 

 

39.4 Spring Boot Shiro权限管理【从零开始学Spring Boot】

 

39.3 Spring Boot Shiro权限管理【从零开始学Spring Boot】

 

39.2. Spring Boot Shiro权限管理【从零开始学Spring Boot】

 

39.1 Spring Boot Shiro权限管理【从零开始学Spring Boot】

 

38 Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】 

 

37 Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】 

 

36 Spring Boot Cache理论篇【从零开始学Spring Boot】

 

35 Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】 

 

34Spring Boot的启动器Starter详解【从零开始学Spring Boot】

 

33 Spring Boot 监控和管理生产环境【从零开始学Spring Boot】

 

32 Spring Boot使用@SpringBootApplication注解【从零开始学Spring Boot】 

 

31 Spring Boot导入XML配置【从零开始学Spring Boot】

 

 

 

更多查看博客: http://412887952-qq-com.iteye.com/





相信使用过Spring的众多开发者都知道Spring提供了非常好用的 JavaMailSender接口实现邮件发送。在Spring Boot的Starter模块中也为此提供了自动化配置。下面通过实例看看如何在Spring Boot中使用 JavaMailSender 发送邮件。

快速入门

在Spring Boot的工程中的 pom.xml 中引入 spring-boot-starter-mail 依赖:

<dependency>  
    <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 

如其他自动化配置模块一样,在完成了依赖引入之后,只需要在 application.properties 中配置相应的属性内容。

下面我们以QQ邮箱为例,在 application.properties 中加入如下配置(注意替换自己的用户名和密码):

spring.mail.host=smtp.qq.com  
spring.mail.username=用户名  //发送方的邮箱
spring.mail.password=密码  //对于qq邮箱而言 密码指的就是发送方的授权码
spring.mail.properties.mail.smtp.auth=true  
spring.mail.properties.mail.smtp.starttls.enable=true  
spring.mail.properties.mail.smtp.starttls.required=true  
注意:spring.mail.password处的值是需要在邮箱设置里面生成的授权码,这个不是真实的密码。

通过单元测试来实现一封简单邮件的发送:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ApplicationTests { @Autowired private JavaMailSender mailSender; @Test public void sendSimpleMail() throws Exception { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("dyc87112@qq.com"); message.setTo("dyc87112@qq.com"); message.setSubject("主题:简单邮件"); message.setText("测试邮件内容"); mailSender.send(message); } } 

到这里,一个简单的邮件发送就完成了,运行一下该单元测试,看看效果如何?

由于Spring Boot的starter模块提供了自动化配置,所以在引入了 spring-boot-starter-mail 依赖之后,会根据配置文件中的内容去创建 JavaMailSender 实例,因此我们可以直接在需要使用的地方直接 @Autowired 来引入邮件发送对象。

对于qq邮箱这样写过后会报错:

1、异常信息:

org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure; message exception details (1) are:
Failed message 1:
javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2046)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:711)
at javax.mail.Service.connect(Service.java:366)
at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:501)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:421)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:307)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:296)

这种错误一般是因为jre的lib下C:\Program Files\Java\jdk1.8.0_51\jre\lib\security,替换2个jar包,参考文档

http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

2、异常信息

org.springframework.mail.MailAuthenticationException: Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 535 Error: ??ê1ó?êúè¨??μ????£?ê?é???′: http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256

at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:424)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:307)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:296)
at com.vcredit.ddcash.monitor.controller.AppTest.testSendSimple(AppTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

发送方必须要开启smtp,获取到的授权码,界面如下:

 3、异常信息:

org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: STARTTLS is required but host does not support STARTTLS. Failed messages: javax.mail.MessagingException: STARTTLS is required but host does not support STARTTLS; message exception details (1) are:
Failed message 1:
javax.mail.MessagingException: STARTTLS is required but host does not support STARTTLS
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:721)
at javax.mail.Service.connect(Service.java:366)
at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:501)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:421)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:307)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:296)
at com.vcredit.ddcash.monitor.controller.AppTest.testSendSimple(AppTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

换成公司企业邮箱报错,通过将properties文件的内容修改就可以了,这里的用户密码就是自己的邮箱密码(这点不同于qq邮箱)

spring.mail.properties.mail.smtp.starttls.enable=false
spring.mail.properties.mail.smtp.starttls.required=false

 

    • 发送HTML格式的邮件
@Test
public void testSendHtml() {
    MimeMessage message = null; try { message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(username); helper.setTo("398986099@qq.com"); helper.setSubject("标题:发送Html内容"); StringBuffer sb = new StringBuffer(); sb.append("<h1>大标题-h1</h1>") .append("<p style='color:#F00'>红色字</p>") .append("<p style='text-align:right'>右对齐</p>"); helper.setText(sb.toString(), true); } catch (MessagingException e) { e.printStackTrace(); } javaMailSender.send(message); }

注意:这里创建的是MimeMessageHelper,且在调用setText时需要在第二个参数传入true,这样才会使用HTML格式发送邮件

 

通过velocity模板发送邮件:

<dependency> 
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-velocity</artifactId>
</dependency>

@Autowired

private VelocityEngine velocityEngine;

@Test
public void sendTemplateMail() throws Exception {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom("dingfuzhao@vcredit.com");
helper.setTo("dingfuzhao@vcredit.com");
helper.setSubject("主题:模板邮件");
Map<String, Object> model = new HashedMap();
model.put("username", "didi");
String text = VelocityEngineUtils.mergeTemplateIntoString(
velocityEngine, "template.vm", "UTF-8", model);
helper.setText(text, true);
javaMailSender.send(mimeMessage);
}

在resources下建一个templates包 该包下建立一个文件template.vm,内容以html格式随便写

<html> 
<body> 
<h3>你好, ${username}, 这是一封模板邮件!</h3>
</body> 
</html>

 

测试结果:

 


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值