• 发送邮件及消息中间件


    邮件发送过程

    协议:规定了数据传输的格式。

    工具类

    /**
     *
     * @param to            : 邮件接收者
     * @param subject       :主题
     * @param content       :邮件正文
     * @throws Exception
     */
    public static void sendMsg(String to ,String subject ,String content) throws Exception{
       //1.发送邮件设置
       Properties props = new Properties();
       props.setProperty("mail.smtp.host", "smtp.sina.com");  //设置主机地址   smtp.qq.com    smtp.sina.com
       props.setProperty("mail.smtp.auth", "true");//认证
    
       //2.产生一个用于邮件发送的Session对象
       Session session = Session.getInstance(props);
    
       //3.产生一个邮件的消息对象
       MimeMessage message = new MimeMessage(session);
    
       //4.设置消息的发送者
       Address fromAddr = new InternetAddress("004@sina.com");
       message.setFrom(fromAddr);
    
       //5.设置消息的接收者
       Address toAddr = new InternetAddress(to);
       //TO 直接发送  CC抄送    BCC密送
       message.setRecipient(MimeMessage.RecipientType.TO, toAddr);
    
       //6.设置主题
       message.setSubject(subject);
       //7.设置正文
       message.setText(content);
    
       //8.准备发送,得到火箭
       Transport transport = session.getTransport("smtp");
       //9.设置火箭的发射目标
       transport.connect("smtp.sina.com", "004@sina.com", "loveyou");
       //10.发送
       transport.sendMessage(message, message.getAllRecipients());
    
       //11.关闭
       transport.close();
    }
    

    新增用户发送邮件

    /**
     * 新增用户
     *      1.获取表单数据构造user对象
     *      2.添加对应的企业属性
     * 更新用户
     */
    @RequestMapping(value = "/edit" , name = "编辑用户")
    public String edit(User user) {
       user.setCompanyId(companyId);
       user.setCompanyName(companyName);
       //1.判断是否具有id属性
       if(UtilFuns.isEmpty(user.getId())) {
          String password = user.getPassword();
          //2.没有id,保存
          userService.save(user);
          //发送邮件
          try{
             MailUtil.sendMsg(user.getEmail(),"恭喜申请成功","尊敬的xxx用户您好:欢迎加入xxxxx,您的登录账号为:"+
                   user.getEmail()+",登录密码为:"+password);//接收者,主体,正文
          }catch (Exception e) {
             e.printStackTrace();
          }
       }else{
          //3.具有id,更新
          userService.update(user);
       }
       return "redirect:/system/user/list.do";
    }
    

    消息中间件

    概述

    消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,
    它可以在分布式环境下扩展进程间的通信。消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,
    实现高性能,高可用,可伸缩和最终一致性架构。 对于消息中间件,常见的角色大致也就有 Producer(生产者)、Consumer(消费者)。

    常见消息中间件

    常见的消息中间件产品:
    (1 )ActiveMQ
    ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持 JMS1.1 和J2EE 1.4 规范的 JMS Provider 实现。
    (2)RabbitMQ
    AMQP 协议的领导实现,支持多种场景。淘宝的 MySQL 集群内部有使用它进行通讯,OpenStack 开源云平台的通信组件,最先在金融行业得到运用。
    (3)ZeroMQ
    史上最快的消息队列系统
    (4)Kafka
    Apache 下的一个子项目 。特点:高吞吐,在一台普通的服务器上既可以达到 10W/s 的吞吐速率;完全的分布式系统。适合处理海量数据。

    消息的两种模式

    ActiveMQ

    软件安装

    绿色版解压即可

    spring整合ActiveMQ

    消息生产者

    引入坐标

    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>
    
    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.11.2</version>
        </dependency>
        <dependency>
            <groupId>javax.jms</groupId>
            <artifactId>javax.jms-api</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

    配置文件

    <?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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:amq="http://activemq.apache.org/schema/core"
    xmlns:jms="http://www.springframework.org/schema/jms"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/jms
    http://www.springframework.org/schema/jms/spring-jms.xsd
    http://activemq.apache.org/schema/core
    http://activemq.apache.org/schema/core/activemq-core.xsd">

    <context:component-scan base-package="cn.jia"></context:component-scan>

    <!--
    spring和activeMq整合:通过整合JmsTemplate对象进行消息发送
    -->
    <!--1.连接工厂-->
    <bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
    </bean>
    <!--2.spring管理连接工厂-->
    <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="activeMQConnectionFactory"></property>
    </bean>
    <!--3.指定目的地址:queue或者topic-->
    <bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
    <!--value:表示在activeMQ中创建的列表名称-->
    <constructor-arg value="test-spring-queue"></constructor-arg>
    </bean>
    <!--4.通过连接工厂创建jmstemplate-->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"></property>
    </bean>

    <!--3.指定目的地址:queue或者topic-->
    <bean id="topic" class="org.apache.activemq.command.ActiveMQTopic">
    <!--value:表示在activeMQ中创建的列表名称-->
    <constructor-arg value="test-spring-topic"></constructor-arg>
    </bean>
    </beans>

    消息提供者java代码

    @Component
    public class ActivemqProducer {
    
        @Autowired
        private Destination queue; //注入queue
    
        @Autowired
        private Destination topic; //注入topic
    
        @Autowired
        private JmsTemplate jmsTemplate; //注入工具类
    
        public void sendQueue(final String msg){
            //参数1:表示消息要传递到哪个队列中   参数2:消息创建器对象
            jmsTemplate.send(queue, new MessageCreator() {
                //session:消息对象
                public Message createMessage(Session session) throws JMSException {
                    //创建一个字符串类型消息
                    TextMessage textMessage = session.createTextMessage(msg);
                    return textMessage;
                }
            });
        }
    
        public void sendTopic(final String msg){
            //参数1:表示消息要传递到哪个队列中   参数2:消息创建器对象
            jmsTemplate.send(topic, new MessageCreator() {
                //session:消息对象
                public Message createMessage(Session session) throws JMSException {
                    //创建一个字符串类型消息
                    TextMessage textMessage = session.createTextMessage(msg);
                    return textMessage;
                }
            });
        }
    }

    测试

    // @RunWith(SpringJUnit4ClassRunner.class)
    @RunWith(SpringRunner.class)
    @ContextConfiguration("classpath:applicationContext-jms.xml")
    public class TestActiveMq {
    
    
        @Autowired
        private ActivemqProducer activemqProducer;
    
        @Test
        //测试queue
        public void test1(){
            activemqProducer.sendQueue("hello123");
        }
    
        @Test
        //测试topic
        public void test2(){
            activemqProducer.sendTopic("hello tom");
        }
    }

    消息消费者

    配置文件

     <context:component-scan base-package="cn.jia"></context:component-scan>
    
        <!--
            spring和activeMq整合:通过整合JmsTemplate对象进行消息发送
        -->
        <!--1.连接工厂-->
        <bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
            <property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
        </bean>
        <!--2.spring管理连接工厂-->
        <bean id="connectionFactory"  class="org.springframework.jms.connection.CachingConnectionFactory">
            <property name="targetConnectionFactory" ref="activeMQConnectionFactory"></property>
        </bean>
    
        <!--告知消费者业务类,去哪个队列中获取消息-->
        <!--配置监听器管理器
           配置的都是基于queue类型的消息监听    -->
        <jms:listener-container destination-type="queue" connection-factory="connectionFactory">
            <jms:listener destination="test-spring-queue" ref="activeMqConsumer"/>
        </jms:listener-container>
    
        <!--告知消费者业务类,去哪个队列中获取消息-->
        <!--配置监听器管理器
           配置的都是基于topic类型的消息监听    -->
        <jms:listener-container destination-type="topic" connection-factory="connectionFactory">
            <jms:listener destination="test-spring-topic" ref="activeMqTopicConsumer"/>
        </jms:listener-container>
    
    </beans>

    web.xml配置监听器

       <!-- 监听器监听其他的spring配置文件 -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-jms.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    </web-app>

    测试

    @Component
    public class ActiveMqConsumer implements MessageListener{
    
    
        public void onMessage(Message message) {
            //把消息类型转换成字符串类型消息
            TextMessage textMessage = (TextMessage) message;
            try {
                //输出消息
                System.out.println("Queue: "+textMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
    @Component
    public class ActiveMqTopicConsumer implements MessageListener {
    
        public void onMessage(Message message) {
            //把消息类型转换成字符串类型消息
            TextMessage textMessage = (TextMessage) message;
            try {
                //输出消息
                System.out.println("Topic: "+textMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }

    改造邮件发送

    引入坐标

      <!--activeMq-->
            <dependency>
                <groupId>org.apache.activemq</groupId>
                <artifactId>activemq-all</artifactId>
                <version>${activemq.version}</version>
            </dependency>
            <dependency>
                <groupId>javax.jms</groupId>
                <artifactId>javax.jms-api</artifactId>
                <version>2.0.1</version>
            </dependency>

          <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jms</artifactId>
          <version>${spring.version}</version>
          </dependency>

    编写配置

    哪个发邮件在哪编写配置文件

    <?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:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:amq="http://activemq.apache.org/schema/core"
           xmlns:jms="http://www.springframework.org/schema/jms"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/jms
            http://www.springframework.org/schema/jms/spring-jms.xsd
            http://activemq.apache.org/schema/core
            http://activemq.apache.org/schema/core/activemq-core.xsd">
    
       <!-- <context:component-scan base-package="cn.jia"></context:component-scan>-->
    
        <!--
            spring和activeMq整合:通过整合JmsTemplate对象进行消息发送
        -->
        <!--1.连接工厂-->
        <bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
            <property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
        </bean>
        <!--2.spring管理连接工厂-->
        <bean id="connectionFactory"  class="org.springframework.jms.connection.CachingConnectionFactory">
            <property name="targetConnectionFactory" ref="activeMQConnectionFactory"></property>
        </bean>
        <!--3.指定目的地址:queue或者topic-->
        <bean id="queue" class="org.apache.activemq.command.ActiveMQQueue">
            <!--value:表示在activeMQ中创建的列表名称-->
            <constructor-arg value="email-queue"></constructor-arg>
        </bean>
        <!--4.通过连接工厂创建jmstemplate-->
        <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory" ref="connectionFactory"></property>
        </bean>
    
    </beans>

    service实现类

     @Autowired
        private Destination queue; //点对点消息模型
    
        @Autowired
        private JmsTemplate jmsTemplate;
    
        public void save(User user) {
            String pwd = user.getPassword();
            //1、保存用户
            user.setId(UUID.randomUUID().toString());
            user.setPassword(Encrypt.md5(user.getPassword(),user.getEmail()));
            userDao.save(user);
    
            //2、给用户发送邮件
            jmsTemplate.send(queue, new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {
                    MapMessage mapMessage = session.createMapMessage();
                    mapMessage.setStringProperty("to",user.getEmail());
                    mapMessage.setStringProperty("subject","xxx邮件");
                    mapMessage.setStringProperty("content","欢迎您加入xxx有限公司!您的账号为:"+user.getEmail()+",初始密码是:"+pwd);
                    return mapMessage;
                }
            });

        /*try {
        MailUtil.sendMsg(user.getEmail(),"xxx邮件","欢迎您加入xxx有限公司!您的账号为:"+user.getEmail()+",初始密码是:"+pwd);
        } catch (Exception e) {
        e.printStackTrace();
         }*/

    新建消费者模块

    引入坐标(父工程已有)

    依赖common里的发送邮件的工具类

    配置文件

    <?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:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:amq="http://activemq.apache.org/schema/core"
           xmlns:jms="http://www.springframework.org/schema/jms"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/jms
            http://www.springframework.org/schema/jms/spring-jms.xsd
            http://activemq.apache.org/schema/core
            http://activemq.apache.org/schema/core/activemq-core.xsd">
    
        <context:component-scan base-package="cn.jia"></context:component-scan>
    
        <!--
            spring和activeMq整合:通过整合JmsTemplate对象进行消息发送
        -->
        <!--1.连接工厂-->
        <bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
            <property name="brokerURL" value="tcp://127.0.0.1:61616"></property>
        </bean>
        <!--2.spring管理连接工厂-->
        <bean id="connectionFactory"  class="org.springframework.jms.connection.CachingConnectionFactory">
            <property name="targetConnectionFactory" ref="activeMQConnectionFactory"></property>
        </bean>
    
        <!--告知消费者业务类,去哪个队列中获取消息-->
        <!--配置监听器管理器
           配置的都是基于queue类型的消息监听    -->
        <jms:listener-container destination-type="queue" connection-factory="connectionFactory">
            <jms:listener destination="email-queue" ref="emailListener"/>
        </jms:listener-container>
    
    
    
    </beans>

    web.xml配置监听器

        <!-- 监听器监听其他的spring配置文件 -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/applicationContext-jms.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    </web-app>

    emailListener

    @Component
    public class EmailListener implements MessageListener{
        //参数:队列中的消息对象
        public void onMessage(Message message) {
            try {
                //1、获取消息数据
                MapMessage mapMessage = (MapMessage) message;
                String to = mapMessage.getStringProperty("to");
                String subject = mapMessage.getStringProperty("subject");
                String content = mapMessage.getStringProperty("content");
                //2、发送邮件
                MailUtil.sendMsg(to,subject,content);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
  • 相关阅读:
    Java 中的 volatile 关键字
    Java 隐式锁
    导致并发程序出问题的根本原因是什么?
    BZOJ_2434_[Noi2011]阿狸的打字机_AC自动机+出栈入栈序+树状数组
    BZOJ_5368_[Pkusc2018]真实排名_组合数
    CF上的3道小题(2)
    BZOJ_4199_[Noi2015]品酒大会_后缀自动机
    BZOJ_4566_[Haoi2016]找相同字符_后缀自动机
    BZOJ_3172_[Tjoi2013]单词_后缀自动机
    BZOJ_3998_[TJOI2015]弦论_后缀自动机
  • 原文地址:https://www.cnblogs.com/WonderfulU/p/11217619.html
Copyright © 2020-2023  润新知