邮件服务对于项目来说属于基础性服务了,使用spring-mail实现起来真是太简单了,但是其中还是会有一点小问题需要注意下,下面就来讲下结合spring-boot实现邮件服务的封装。

其实封装基础服务无非就以下几种形式 基础工具类 优点:简单实用,发送快捷 缺点:应用耦合度高,对于目前趋近于分布式系统来说,这样做是致命的

dubbo服务 因为我们公司用的是dubbo,所以就以dubbo来举例了。无非就是代表了rpc、http等类型的通信模式。 优点:应用解耦,部署不会影响到任何现有应用,可动态 缺点:在大型分布式项目中,需要依赖api,略复杂

mq异步通信

优点:对于MQ通信是我所喜欢的解耦方式,实现简单,通信快捷 缺点:实现略微复杂点,要注意监控消息的可靠性和处理的幂等性问题

对于以上三种方式我是比较倾向于MQ,所以下面简单说下MQ 邮件处理的封装

1、依赖包  spring-boot-starter-amqp spring-boot-starter-mail

2、首先你要配置MQ,这就不再叙说了,想看MQ配置的可以翻翻以前的文章

3、我直接说下接收方的使用

package com.ecej.nove.sms.mail;import javax.annotation.Resource;import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import com.ecej.nove.base.mail.BaseMail;/*** 接收邮件信息* * @author QIANG**/
@Component
@RabbitListener(queues = "ecejmail")
public class MailReceiverService {private Logger LOG = LoggerFactory.getLogger(MailReceiverService.class);@Resourceprivate MailSendService mailSendService;@Value("${mail.close.flag}")private boolean flag;@RabbitHandlerpublic void ReceiverMessage(BaseMail mail) {//开关if (flag)return;if (MapUtils.isEmpty(mail.getPaths())) {mailSendService.sendMail(mail);} else {mailSendService.sendMailAndFile(mail);}LOG.info("Receiver Mail Obj !");}@RabbitHandlerpublic void ReceiverMessage(String mail) {System.out.println(mail);}}复制代码

4、编写发送mail的实际方法,使用异步线程发送

package com.ecej.nove.sms.mail;import java.io.File;import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import com.ecej.nove.base.mail.BaseMail;@Service("mailSendService")
public class MailSendService {private Logger LOG = LoggerFactory.getLogger(MailSendService.class);@Value("${spring.mail.username}")private String from;@Resourceprivate JavaMailSender mailSender;@Async("mailAsync")public void sendMail(BaseMail mail) {SimpleMailMessage message = new SimpleMailMessage();message.setFrom(from);message.setTo(mail.getTo());message.setSubject(mail.getSubject());message.setText(mail.getText());message.setBcc(mail.getBcc());message.setCc(mail.getCc());mailSender.send(message);LOG.info("发送邮件成功,邮件详情:{}", message.toString());}@Async("mailAsync")public void sendMailAndFile(BaseMail mail) {try {MimeMessage mimeMessage = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);helper.setFrom(from);helper.setTo(mail.getTo());helper.setSubject(mail.getSubject());helper.setText(mail.getText());helper.setBcc(mail.getBcc());helper.setCc(mail.getCc());mail.getPaths().entrySet().stream().forEach(set -> {FileSystemResource file = new FileSystemResource(new File(set.getValue()));try {helper.addAttachment(set.getKey(), file);} catch (MessagingException e) {LOG.error("SAVE MAIL FILE ERROR!", e);}});mailSender.send(mimeMessage);LOG.info("发送邮件成功,邮件详情:{}", mail.toString());} catch (Exception e) {LOG.error("SEND MAIL ERROR !", e);}}
}```
5、异步线程配置
复制代码

package com.ecej.nove.sms.config;

import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**

  • 配置异步任务分发
  • @author QIANG

*/ @Configuration @EnableScheduling @EnableAsync public class ExecutorConfig {

@Value("${sms.executor.corePoolSize}")
private int corePoolSize;@Value("${sms.executor.maxPoolSize}")
private int maxPoolSize;@Value("${sms.executor.queueCapacity}")
private int queueCapacity;@Bean(name = "mailAsync")
public Executor mailAsync() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(corePoolSize);executor.setMaxPoolSize(maxPoolSize);executor.setQueueCapacity(queueCapacity);executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.setThreadNamePrefix("MailExecutor-");executor.initialize();return executor;
}
复制代码

}


6、配置
复制代码

mail.close.flag=@ecej.mail.close.flag@ spring.mail.host=@ecej.mail.host@ spring.mail.username=@ecej.mail.username@ spring.mail.password=@ecej.mail.password@ spring.mail.properties.mail.smtp.auth=@ecej.properties.mail.smtp.auth@ spring.mail.properties.mail.smtp.starttls.enable=@ecej.properties.mail.smtp.starttls.enable@ spring.mail.properties.mail.smtp.starttls.required=@ecej.properties.mail.smtp.starttls.required@


至此,通过MQ接收对象,然后发送邮件的需求就完成了,这个简单实用的接收端完成了,可以发送普通和带附件的邮件。当然,发送HTML之类的只是增加实例方法就行了。然而,事情并没有这么简单,如果我要正常连接某邮件服务器这样就可以了。但是现在大多数,比喻集团邮件服务器是需要进行验证的。如果只有以上配置,不好意思,咔嚓给你来个异常。![异常来咯](http://upload-images.jianshu.io/upload_images/4405663-c4926d8c13c49acc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)如此无奈,经各种官方打听,获得如下解决方案(网上什么加证书啊乱七八糟的,根本不靠谱)。
先来个官方版说法:
>When using SSL/TLS, it's important to ensure that the server you connect
to is actually the server you expected to connect to, to prevent "man in
the middle" attacks on your communication.  The recommended technique is
to configure the Java keystore using one of the methods described above.
If, for some reason, that approach is not workable, it's also possible
to configure the SSL/TLS implementation to use your own TrustManager
class to evaluate whether to trust the server you've connected to.扯这么一大串,简单点说就是你可以自己搞个SSLSocketFactory自己去玩。
直接上菜:
复制代码

package com.ecej.nove.sms.mail;

import java.io.IOException; import java.net.InetAddress; import java.net.Socket;

import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager;

public class DummySSLSocketFactory extends SSLSocketFactory { private SSLSocketFactory factory;

public DummySSLSocketFactory() {try {SSLContext sslcontext = SSLContext.getInstance("TLS");sslcontext.init(null, new TrustManager[] { new DummyTrustManager() }, null);factory = sslcontext.getSocketFactory();} catch (Exception ex) {// ignore}
}public static SocketFactory getDefault() {return new DummySSLSocketFactory();
}@Override
public Socket createSocket() throws IOException {return factory.createSocket();
}@Override
public Socket createSocket(Socket socket, String s, int i, boolean flag) throws IOException {return factory.createSocket(socket, s, i, flag);
}@Override
public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr1, int j) throws IOException {return factory.createSocket(inaddr, i, inaddr1, j);
}@Override
public Socket createSocket(InetAddress inaddr, int i) throws IOException {return factory.createSocket(inaddr, i);
}@Override
public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {return factory.createSocket(s, i, inaddr, j);
}@Override
public Socket createSocket(String s, int i) throws IOException {return factory.createSocket(s, i);
}@Override
public String[] getDefaultCipherSuites() {return factory.getDefaultCipherSuites();
}@Override
public String[] getSupportedCipherSuites() {return factory.getSupportedCipherSuites();
}
复制代码

}

GO ON DOING...
复制代码

package com.ecej.nove.sms.mail;

import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class DummyTrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] cert, String authType) { // everything is trusted }

public void checkServerTrusted(X509Certificate[] cert, String authType) {// everything is trusted
}public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];
}
复制代码

}

增加一点点配置文件
复制代码

spring.mail.properties.mail.imap.ssl.socketFactory.fallback=false spring.mail.properties.mail.smtp.ssl.socketFactory.class=com.ecej.nove.sms.mail.DummySSLSocketFactory

SO,这下这个恶心的小问题就解决了,附赠原版解读(有事还得找官方)
http://www.oracle.com/technetwork/java/javamail145sslnotes-1562622.html **小结**
spring 这一大群配置文件我还真记不住,所以给留一个全面的api
https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html
***
**关注公众号,获取最新推送**![狍狍的日常生活](http://upload-images.jianshu.io/upload_images/4405663-ed916c1cdcfdbf15.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)复制代码

转载于:https://juejin.im/post/5d0725dfe51d4556bc066f6e

Spring Boot 实际应用(三)发送邮件实现相关推荐

  1. Spring Boot中使用JavaMailSender发送邮件

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

  2. Spring Boot:(三)开发Web应用之Thymeleaf篇

    Spring Boot:(三)开发Web应用之Thymeleaf篇 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Spring Boot ...

  3. Spring boot入门(三):集成AdminLTE(Freemarker),结合generate代码生成器,利用DataTable和PageHelper分页...

    Spring boot入门(三):SpringBoot集成结合AdminLTE(Freemarker),利用generate自动生成代码,利用DataTable和PageHelper进行分页显示 标题 ...

  4. Spring Boot 2.0(三):Spring Boot 开源软件都有哪些?

    2016年 Spring Boot 还没有被广泛使用,在网上查找相关开源软件的时候没有发现几个,到了现在经过2年的发展,很多互联网公司已经将 Spring Boot 搬上了生产,而使用 Spring ...

  5. maven web项目导入sts_Spring Boot2 系列教程(二)创建 Spring Boot 项目的三种方式

    我最早是 2016 年底开始写 Spring Boot 相关的博客,当时使用的版本还是 1.4.x ,文章发表在 CSDN 上,阅读量最大的一篇有 43W+,如下图: 2017 年由于种种原因,就没有 ...

  6. spring boot 使用 javax.mail发送邮件常见错误Authentication failed、Mail server connection failed

    最近做系统内审批业务,需要发送邮件,在本地使用公司邮箱测试时,是没有问题的,没有使用发件服务器验证: 项目使用的是spring boot 2.x; 初始配置文件: spring:mail:host: ...

  7. Spring Boot系列(三)、Spring Boot视图技术(Jsp、FreeMarker、Thymeleaf)

    三.Spring Boot视图技术 3.1 Spring Boot常见的有三种视图整合 3.2 第一种视图整合jsp 1 pom.xml文件: 2 然后新建JSP视图的访问和存储目录webapp/WE ...

  8. spring Boot手把手教学(6):发送邮件

    文章目录 1.前言 2.安装依赖 3.添加配置信息 4.代码实现 5.功能扩展 5.1.发送HTML格式邮件 5.2.发送带附件的邮件 5.3.使用`thymeleaf`模板发送邮件 6.完整代码 1 ...

  9. Spring Boot 教程(三): Spring Boot 整合Mybatis

    教程简介 本项目内容为Spring Boot教程样例.目的是通过学习本系列教程,读者可以从0到1掌握spring boot的知识,并且可以运用到项目中.如您觉得该项目对您有用,欢迎点击收藏和点赞按钮, ...

最新文章

  1. flutter 真机无法调试 sdk报错_Flutter - 不一样的跨平台解决方案
  2. Jekyll博客统计访问量,阅读量工具总结--LeanCloud,不蒜子,Valine,Google Analytics
  3. 大数据入门之Hadoop基础学习
  4. python request-Python之request模块-基础用法
  5. php正则运用,php中常用的正则表达式的介绍及应用实例代码
  6. c++ 如何给 “运行中“ 的线程传递数据;
  7. 一维数组名与二维数组名的关联
  8. matlab里inline定义矩阵,Matlab中的inline函数_matlab中inline函数
  9. OJ1052: 数列求和4(C语言)
  10. 编译U-boot时,make[1]: *** 没有规则可以创建mkimage.o”
  11. 二维码生成器如何制作圆形二维码
  12. 计算机模拟题操作题错误,计算机模拟试卷操作题答案.doc
  13. bandicam的延迟问题和画质问题
  14. Android一键加群实现
  15. Cisco网站模块 14 - 15:网络应用通信考试试题及答案
  16. 克孜勒苏柯尔克孜自治州谷歌高清卫星地图下载
  17. Houdini abcobj 导入 Maya
  18. 09组团队项目-Alpha冲刺-2/6
  19. cura同时打印多个东西,cura同时打开多个模型,cura打开多个stl
  20. layui数据表格的使用

热门文章

  1. 联想笔记本java环境变量_联想ThinkPad笔记本如何添加系统环境变量?
  2. STAT 7008 - Assignment Question 1 (hashtag analysis)
  3. 汇编语言(王爽 第三版)检测点
  4. CentOS 安装以及配置Apache php mysql
  5. Linux下查看CPU信息、机器型号等硬件信息
  6. 做网页很实用代码集合和CSS制作网页小技巧整理
  7. 由HEAP Corruption DETECTED查到的
  8. 静态代码块、非静态代码块、构造函数执行顺序
  9. Clover支持目录多标签页
  10. Kerberos认证过程学习理解