基于SpringBoot:ActiveMQ 之邮箱发送

在项目中。实现邮箱发送的方式有很多种。
最经典的就是用javaMailSender的方式实现。

先在邮箱中申请了smtp,接着配置application.properties里面的参数

spring.mail.protocol=smtp
spring.mail.host=smtp.qq.com
spring.mail.username=隐藏
spring.mail.password=隐藏
spring.mail.defaultEncoding=UTF-8
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

添加maven依赖

        
            org.springframework.boot
            spring-boot-starter-mail
        

实现方法


@Service
public class EmailServiceImpl implements EmailService {

//发送邮件的用户名
    @Value("${spring.mail.username}")
    private String sender;

@Override
    public void sendEmail(String to, String subject, StringBuffer content) {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper helper =null;
        try {
            helper = new MimeMessageHelper(message,true);
            helper.setFrom(sender);
            helper.setSubject(subject);
            helper.setTo(to);
            helper.setText(content.toString(),true);
            javaMailSender.send(message);
            logger.info("邮件已经发送");
        }catch (MessagingException e){
            logger.error("邮件发送异常",e);
        }
    }

然后嵌套在controller中。
注入改该方法。直接使用sendEmail

 	String code = users.getActiCode();
        String subject = "激活邮件";
        StringBuffer context = new StringBuffer();
        context.append("

你好:"+users.getUserName()+"

") .append("

激活请点击:


Click Me

"); emailService.sendEmail(users.getUserEmail(),subject,context);

但是会遇到一种情况。就是必须等待它发送完邮件才能进行下一个动作。
容易造成假卡死的状况。如果。与此同时多个用户都在点击这个发送邮件的动作。可能服务器会崩溃。

ActiveMQ使用

消息中间件。具体使用消息队列(MQ)的优点还有概念就不解释了。网上很多。
但是我们需要的业务要求是

  • 让发送邮件这个事情丢到消息中间件中,也就是将其作为生产者。
  • 消费者收到生产者的消息后,就会开始执行发送邮件这个动作。
  • 用户就不用等待了。让消息中间件处理。我们只需要等待consumer发送邮件。

有很多种MQ,我用的是ActiveMQ

下载ActiveMQ

  • 官网下载。解压。找到bin–>win64–>activemq.bat运行
  • 访问http://localhost:8161,账号密码都默认admin

添加maven依赖

        
        
            org.springframework.boot
            spring-boot-starter-mail
        
        
            org.apache.activemq
            activemq-pool
        
	  
            org.springframework.boot
            spring-boot-starter-activemq
        

添加properties

我这里多创建了一个properties。为了方便区别

application.properties

spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
#下面这些不是太必要
#处理序列化对象需要用到的配置
#如果需要这里需要针对queue和topics的选择添加,我没写
spring.activemq.packages.trusted=true
spring.activemq.packages.trust-all=true
spring.activemq.pool.enabled=false
spring.activemq.pool.max-connections=50
spring.activemq.pool.idle-timeout=30000

email.properties

spring.mail.protocol=smtp
spring.mail.host=smtp.qq.com
spring.mail.username=隐藏
spring.mail.password=隐藏
spring.mail.defaultEncoding=UTF-8
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

#这里是一个业务需要用得的地址,不需要跟着我添加
com.mailUrl=http://localhost:8081/

创建生产者

记得创建相应的接口

@Slf4j
@Service
public class ActiveMQServiceImpl implements ActiveMQService {
    @Autowired
    JmsTemplate template;

    /**
     *@Auther kiwi
     *@Data 2019/9/8
    * 发送邮件
     */
    @Override
    public void sendEmail(String to, String subject, String content) throws IOException {
        template.send("registerBySystem", new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {
                    MapMessage mapMessage = session.createMapMessage();
                    mapMessage.setString("content", content);
                    mapMessage.setString("address", to);
                    mapMessage.setString("subject", subject);
                    return mapMessage;
                }
            });
        log.info("发送给消费者");

    }
}

to是发送过去的邮箱,subject是标题,content是邮件的内容
这里使用了JmsTemplate的send方法。第一个参数是生产者发布的名称。后面是传入Message的值,通过这里的Message作为中间值。

消费者

注意,消费者必须加上@Service或者@Component
消费者才能检测到

@Slf4j
@Service
public class ConsumerService {

    @Autowired
    private EmailUtil emailUtil;
    /**
     * 通过监听目标队列实现功能
     */
    @JmsListener(destination = "registerBySystem")
    public void sendMail(Message message) throws Exception {
        MapMessage mapMessage = (MapMessage) message;
        String content = mapMessage.getString("content");
        String address = mapMessage.getString("address");
        String subject = mapMessage.getString("subject");
        emailUtil.sendEmail(address,subject,content);
    }

}

通过注解@JmsListener里面对生产者名称“registerBySystem”的监听。
然后通过message的值,传入sendEmail。
也就是这里,我们开始出现发送邮件的动作。

发送邮件


@Slf4j
@Component
@PropertySource(value = {"classpath:email.properties"})
public class EmailUtil {

    @Value("${spring.mail.username}")
    private String sender;

    @Value("${spring.mail.host}")
    private String host;

    @Value("${spring.mail.password}")
    private String pwd;


    public void sendEmail(String to, String subject, String content) throws Exception {

  
        Properties props = new Properties();

        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.host", host);
        props.setProperty("mail.smtp.auth", "true");
        Session session = Session.getDefaultInstance(props);
        // 开启debug模式,可以看到更多详细的输入日志
        MimeMessage message = this.addEmail(session,to,subject, content);

        //获取传输通道
        Transport transport = session.getTransport();
        transport.connect(host, sender, pwd);
        //连接,并发送邮件
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();


    }
        /**
         * 创建邮件
         */
        public MimeMessage addEmail(Session session,String to, String subject, String content) throws Exception {
            // 根据会话创建邮件
            MimeMessage msg = new MimeMessage(session);

            // 设置发送邮件方
            msg.setFrom(new InternetAddress(sender));
            // 设置邮件接收方
            msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            // 设置邮件标题
            msg.setSubject(subject, "utf-8");
            msg.setContent(content,"text/html;charset=utf-8");
            // 设置显示的发件时间
            msg.setSentDate(new Date());
            // 保存设置
            msg.saveChanges();
            return msg;
        }

}


具体实现注册很详细了。
注意。在刚刚的ConsumerService中。一定要Autowired该方法。
才能在这里通过@Value获取email.properties的值

邮件模板

也就是content参数

public class EmailTemplate {

    /**
     *@Auther kiwi
     *@Data 2019/9/8
     @param  * @param
     * 注册模板
     *@reutn java.lang.String
    */
    public static String registerTemplate(String sendUrl,String code) throws IOException {
        String fileName = "pod-scale-alarm.html";
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName);
        BufferedReader fileReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        try {
            while ((line = fileReader.readLine()) != null) {
                buffer.append(line);
            }
        } catch (Exception e) {
            log.error("读取文件失败,fileName:{}", fileName, e);
        } finally {
            inputStream.close();
            fileReader.close();
        }

        String contentText = "以下是需要点击的链接, 进入便可完成注册.Click Me";
        //邮件表格header
        String header = "商品管理(itemManagement)订单管理(orderManagement)用户管理(userManagement)系统管理(systemManagement)调度任务(Scheduled Tasks)";
        StringBuilder linesBuffer = new StringBuilder();
        linesBuffer.append("" + "four menu" + "" + "four menu" + "" + "three menu" + "" +
                "" + "two menu" + "" + "two menu" + "");

        String emailHeadColor = "#8A2BE2";
        String date = DateFormatUtils.format(new Date(), "yyyy/MM/dd HH:mm:ss");
        //填充html模板中的五个参数
        String htmlText = MessageFormat.format(buffer.toString(), emailHeadColor, contentText, date, header, linesBuffer.toString());

        //改变表格样式
        htmlText = htmlText.replaceAll("", "");
        htmlText = htmlText.replaceAll("", "");
        return htmlText;
    }
}

pod-scale-alarm.html


Hello
欢迎注册网站 b2b_mall

Hi,

{1}

{2}

{3} {4}

使用activeMQService

//注入,记得加上@PropertySource("email.properties")
    @Resource
    private ActiveMQService activeMQService;
    @Value("${com.mailUrl}")
    private String sendUrl;

//实现

        activeMQService.sendEmail("[email protected]","欢迎注册", EmailTemplate.registerTemplate(sendUrl,"参数地址")));

可根据自己的代码修改

你可能感兴趣的:(框架工具)