QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)

原来有个教程是关于Javamail的,但是那个是自己写Javamail的发送过程,这次不同的是:使用Spring的Mail功能,使用了消息队列。

先看一下设想的场景

不过本文重点不是消息队列,而是使用spring发送邮件。

 首先针对于不会Maven和消息队列的小盆友们

依赖jar包:

spring系列jar包

Javamail 

先建立一个封装Mail信息的类:很好理解,里面的成员变量代表(收件人,主题,内容)

复制代码
package com.mq.entity;

import java.io.Serializable;

public class MailInfo implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -5853264487189248317L;
    private String to;
    private String subject;
    private String content;
    public MailInfo() {
    }
    public MailInfo(String to, String subject, String content) {
        this.to = to;
        this.subject = subject;
        this.content = content;
    }
    public String getTo() {
        return to;
    }
    public void setTo(String to) {
        this.to = to;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    
}
复制代码

然后呢,在classpath下面整一个属性文件,email.properties

复制代码
mail.account=用户名
mail.pass=密码
mail.host=smtp.exmail.qq.com
mail.port=465
mail.protocol=smtp

mail.debug=true
mail.smtp.auth=true
mail.smtp.ssl.enable=true
复制代码

注意:企业邮箱不用什么授权码,就是密码

然后classpath下建立spring配置文件。

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:core="http://activemq.apache.org/schema/core" xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd">

  
    <context:component-scan base-package="com.mq.mail"></context:component-scan>

    <context:property-placeholder location="classpath:email.properties"/>
    
    <!-- 使用SSL,企业邮箱必需! -->
    <bean id="mailSSLSocketFactory" class="com.sun.mail.util.MailSSLSocketFactory">
        <property name="trustAllHosts" value="true"></property>
    </bean>
    
    <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${mail.host}"></property>
        <property name="port" value="${mail.port}"></property>
        <property name="username" value="${mail.account}"></property>
        <property name="password" value="${mail.pass}"></property>
        <property name="protocol" value="${mail.protocol}"></property>
        <property name="defaultEncoding" value="UTF-8"></property>
        <!--  
        -->
        <property name="javaMailProperties">
            <props>
                <!-- 使用SMTP身份验证 -->
                <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
                <!-- Debug模式 -->
                <prop key="mail.debug">${mail.debug}</prop>
                <!-- 使用SSL -->
                <prop key="mail.smtp.ssl.enable">${mail.smtp.ssl.enable}</prop>
                <!-- 配置MailSSLSocketFactory -->
                <prop key="mail.smtp.ssl.socketFactory">mailSSLSocketFactory</prop>
            </props>
        </property>
    </bean>
    
    <bean id="simpleMailMessage" class="org.springframework.mail.SimpleMailMessage">
        <property name="from" value="${mail.account}"></property>
    </bean>

    <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 线程池维护线程的最少数量 -->
        <property name="corePoolSize" value="5" />
        <!-- 线程池维护线程的最大数量 -->
        <property name="maxPoolSize" value="20" />
        <!-- 线程池维护线程所允许的空闲时间 -->
        <property name="keepAliveSeconds" value="30000" />
        <!-- 线程池所使用的缓冲队列 -->
        <property name="queueCapacity" value="1000" />
    </bean>
    
</beans>
复制代码

然后写一个发送邮件类

复制代码
package com.mq.mail;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import com.mq.entity.MailInfo;

@Component
public class SendMail {

    @Autowired
    private JavaMailSender javaMailSender;
    @Autowired
    private SimpleMailMessage simpleMailMessage;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    
    public void send(final MailInfo mailInfo){
        threadPoolTaskExecutor.execute(new Runnable() {
            
            @Override
            public void run() {
                try {
                    simpleMailMessage.setTo(mailInfo.getTo());
                    simpleMailMessage.setSubject(mailInfo.getSubject());
                    simpleMailMessage.setText(mailInfo.getContent());
                    javaMailSender.send(simpleMailMessage);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    
}
复制代码

最后写一个测试类:

复制代码
package com.mq.test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mq.entity.MailInfo;
import com.mq.mail.SendMail;

public class TestMail {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:spring-mail.xml");
        app.start();
        MailInfo mailInfo = new MailInfo("[email protected]", "这是主题", "这是内容");
        app.getBean(SendMail.class).send(mailInfo);
        app.close();
    }
}
复制代码

结果:

下面是Maven+消息队列的部分

我有两个工程,一个是生产者,一个是消费者。都是Maven的web工程。PS:这两个工程加入了mvc,因为本来想做个好玩的东西的,但是太忙了,先放下了,目前只有利用消息队列发送邮件的部分。这也是为啥依赖这么多的原因。

首先是生产者

Maven依赖:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

建立ActiveMQ的属性文件:activemq.properties

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

因为是本地测试,我就在windows系统启动了一个ActiveMQ。

下面建立spring-activemq.xml

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

 spring.xml

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

接下来写代码,目录结构如下:(你不需要考虑controller,以及spring-mvc.xml,以及Food)

建立Mail信息类:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

关于那个Food是我测试着玩的哈哈,满足你的好奇心

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

消息服务接口

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

 消息服务实现:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

最后是测试类,这里使用了springTest。

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

下面是消费者:

依赖和生产者一样的,这里不重复了。activemq.properties也一样。

邮箱属性文件:

复制代码
mail.account=用户名
mail.pass=密码
mail.host=smtp.exmail.qq.com
mail.port=465
mail.protocol=smtp

mail.debug=true
mail.smtp.auth=true
mail.smtp.ssl.enable=true
复制代码

spring-activemq.xml:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

spring-mail.xml:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

spring.xml

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

下面是工程结构:entity不说了,是一样的。

ActiveMQ监听器:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

SendMail:

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

最后测试:

复制代码
package com.mq.test;

import javax.jms.Destination;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@ContextConfiguration(locations={"classpath:spring.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
    
    //@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
    
    //使用@Autowired的话,想使用名称装配可以结合@Qualifier注解进行使用
    
    //@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定, 
    //如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。

    @Autowired
    @Qualifier("queueDestination")
    private Destination destination;
    
    @Test
    public void test(){
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //在单元测试里,如果test方法先于我们要执行的任务结束,会导致任务出错,所以我们这里睡眠了MAX秒,就为了给我们的任务争取时间
    }
}
复制代码

 先启动ActiveMQ,然后执行生产者的test方法,

然后执行消费者的test方法。

 

结果:

 

你运行的时候记得修改收件人哦,别给我发哦。

猜你喜欢

转载自blog.csdn.net/xp_zyl/article/details/80856743