利用activeMQ消息中间件整合spring mail发邮件
来源:互联网 发布:淘宝店铺叫什么名字好 编辑:程序博客网 时间:2024/06/01 11:47
同理消费者监听类一样可以做发短信,微信等等。。。
看这篇文章首先确保你已经阅读过我上一篇spring boot整合activeMQ,实现ptp和topic两者消息模式
配置文件新增了spring mail的相关配置:
spring.mail.username=xxxxxxxxx@163.comspring.mail.password=xxxxxxxxxspring.mail.host=smtp.163.comspring.mail.port=25spring.mail.properties.mail.smtp.auth=truespring.mail.properties.mail.smtp.starttls.enable=truespring.mail.properties.mail.smtp.starttls.required=true
ps:这里提一下,由于使用163邮箱发邮件需要去163邮箱里设置勾选POP3/SMTP服务,选中后会让你设置独立密码,区别于邮箱登陆密码,spring.mail.password这个配置hi的密码就是独立密码而不是邮箱登录密码,否则会报权限报错
pom文件比之前多加入两个:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId></dependency><dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.29</version></dependency>
1.首先为了方便测试我们要先把Customer2里面的@JmsListener监听注解注视掉,这样保证我们只有一个消费者监听消息队列。
2.我们需要在项目里新加一个utils包放工具类,EmailUtil就在其中
@Componentpublic class EmailUtil { @Autowired private JavaMailSender mailSenderAutowired; private static JavaMailSender mailSender; @Value("${spring.mail.username}") private String usernameValue; private static String username; @PostConstruct//bean初始化之前调用 public void init() { this.mailSender = mailSenderAutowired; this.username = usernameValue; } public static void sendEmail(String to, String subject, String text){ SimpleMailMessage message = new SimpleMailMessage(); message = null; message.setFrom(username); message.setTo(to); message.setSubject(subject); message.setText(text); mailSender.send(message); } public static void sendEmailWithFile(String to, String subject, String text, InputStreamSource file) throws MessagingException { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom(username); helper.setTo(to); helper.setSubject(subject); helper.setText(text); helper.addAttachment("附件-1.png", file); mailSender.send(mimeMessage); }}
这里说明一点:
由于是工具类,所以类里面的方法是静态方法,静态方法内部是不能使用类里非静态变量的,所以mailSender和username都定义为静态的,但问题来了,由于定义为静态,代码运行时是无法将配置信息注入到变量里(由于编译起就开辟内存空间,并没有赋值,所以运行期这两个变量是null),于是我们定义两个普通变量来注入配置信息,然后在通过这个注解@PostConstruct在bean初始化之前把普通变量的值交给静态变量,这样运行时就不会报NPE了。
先看一下发邮件方法的入口controller:
@RestController@RequestMapping("/sendEmail")public class SendEmailController { @Autowired private SendEmailService sendEmailService; @GetMapping("/sendEmail/{text}") public void advice(@PathVariable("text") String text){ sendEmailService.advice(text); }}
很简单就一个普通的controller层,再看看service层:
先贴出来平时常规业务逻辑嵌入发邮件功能,这种常规写法存在很多问题,比如:
如果发送邮件出现异常那么发邮件下面的业务逻辑无法正常执行,即使try/catch了,由于这部分代码是同步的,下面的业务代码也需要等待邮件发完才能执行,耦合度很高,高并发情况下还有可能出现阻塞
public interface SendEmailService { void sendEmail(String text); void sendEmailWithFile(String text) throws MessagingException; void advice(String text);}@Servicepublic class SendEmailServiceImpl implements SendEmailService{ @Autowired private ProductService productService; @Override public void advice(String text) {// JSONObject jsonObject = new JSONObject();// jsonObject.put("key","email");// jsonObject.put("text",text);// this.productService.sendMessage(jsonObject.toJSONString()); this.sendEmail(text); System.out.println("邮件发送成,邮件内容是:" + text); //其他业务逻辑... } @Override public void sendEmail(String text) { EmailUtil.sendEmail("xxxxxx@qq.com","测试邮件",text); } @Override public void sendEmailWithFile(String text) throws MessagingException { InputStreamSource file = new FileSystemResource(new File("F:\\pic\\huaji.jpg")); EmailUtil.sendEmailWithFile("xxxxxx@qq.com","测试邮件",text,file); }}
再来看看利用消息队列中间件去发邮件:
好处是把业务逻辑和发邮件功能解耦,即使发邮件失败也不会影响下面的业务逻辑正常执行,由于使用了MQ发邮件和业务逻辑是异步的,下面的代码不必等待邮件发送完毕才执行。
@Servicepublic class SendEmailServiceImpl implements SendEmailService{ @Autowired private ProductService productService; @Override public void advice(String text) { JSONObject jsonObject = new JSONObject(); jsonObject.put("key","email"); jsonObject.put("text",text); this.productService.sendMessage(jsonObject.toJSONString());// this.sendEmail(text); System.out.println("邮件发送成,邮件内容是:" + text); //其他业务逻辑... } @Override public void sendEmail(String text) { EmailUtil.sendEmail("xxxxxx@qq.com","测试邮件",text); } @Override public void sendEmailWithFile(String text) throws MessagingException { InputStreamSource file = new FileSystemResource(new File("F:\\pic\\huaji.jpg")); EmailUtil.sendEmailWithFile("xxxxxx@qq.com","测试邮件",text,file); }}
由于使用mq做的不仅仅是发邮件还有其他功能所以定义一个json对方用key做标识,看一下Customer消费者部分代码:
@Servicepublic class Consumer { @Autowired private SendEmailService sendEmailService; private static int index = 0; // 使用JmsListener配置消费者监听的队列,其中text是接收到的消息 @JmsListener(destination = "zh-topic") public void receiveQueue(String text) throws MessagingException { System.out.println("重试次数:" + index); System.out.println("Consumer收到:"+text); this.index = ++index; JSONObject jsonObject = JSONObject.parseObject(text); if ("email".equals(jsonObject.getString("key"))){//发邮件 this.sendEmail(jsonObject.getString("text")); }else{ //其他业务... } } public void sendEmail(String text) throws MessagingException { this.sendEmailService.sendEmailWithFile(text); }}
这个类里面定义了一个静态的index变量是为了 测试mq在消费消息失败时候的重试机制,我们可以在EmailUtil的发邮件方法里自定义一个异常让发邮件失败,我们观察控制台会发现,activeMQ在消息未消费情况下会默认重试6次,每次重试间隔为1s钟
还要说的是,spring 提供的mail好方便,配置配置通过SimpleMailMessage或MimeMessage就可以发邮件了,添加附件也很方便,比以往使用java mail自己处理方便的多了
- 利用activeMQ消息中间件整合spring mail发邮件
- Spring整合ActiveMQ消息中间件
- linux下 消息中间件ActiveMQ整合spring笔记二 发消息
- 消息中间件-activemq实战之整合Spring(四)
- 消息中间件-activemq实战整合Spring之Topic模式(五)
- spring集成activemq消息中间件
- Spring Java Mail发邮件
- Spring Java Mail发邮件
- 【ActiveMQ】ActiveMQ与Spring实现发邮件
- linux下 消息中间件ActiveMQ整合spring笔记二 接收消息
- Spring整合JMS(消息中间件)
- Spring整合JMS(消息中间件)
- Spring整合JMS(消息中间件)
- Spring整合JMS(消息中间件)
- Spring整合JMS(消息中间件)
- linux mail利用外部邮箱地址发邮件
- Linux下利用mail发邮件
- 消息中间件之ActiveMQ整合Spring实现邮箱发送(四)
- Android实现录屏直播(一)ScreenRecorder的简单分析
- 手机端本地图片或者拍照的上传功能
- MSP430fr6989配合A7129发送一帧无线数据包的操作过程
- hdu Max Sum
- 公开课程表
- 利用activeMQ消息中间件整合spring mail发邮件
- OpenCV移植到ARM(2)
- 那些在电影里看起来很难,实际却毫无技术含量的工作
- 在ubuntu环境下搭建fabric
- VirtualBox下Centos6.9网络配置教程
- 【Kafka源码】KafkaConsumer
- 近期deep learning做图像质量评价(image quality assessment)的论文2
- 【NOIP2017普及组】棋盘
- 05-树9 Huffman Codes(30 point(s)) 最小堆、哈夫曼树、dfs