springboot は、パブリック アカウントのメッセージ送信を完了するために Rabbitmq を統合します

springboot は、パブリック アカウントのメッセージ送信を完了するために Rabbitmq を統合します

1.rabbitmqをダウンロードする

brewを使用してダウンロードできます

brew install rabbitmq

問題があるかもしれませんが、そうでない場合は無視してください

fatal: not in a git directory Error: Command failed with exit 128: git

解決策:
brew install Rabbitmq を個別に実行してから再実行します。

git config --global --add safe.directory /opt/homebrew/Library/Taps/homebrew/homebrew-core
git config --global --add safe.directory /opt/homebrew/Library/Taps/homebrew/homebrew-cask

2. Rabbitmq が成功したかどうかを確認する

実行rabbitmq-server下図が表示されれば起動成功です。
画像の説明を追加してください

3. コードを書く

3.1 pom 依存関係をインポートする

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>whispers</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/>
    </parent>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
    </properties>

    <dependencies>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.2.0</version>
            </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>

        <!-- JSONObject的依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.71</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
            <version>2.2.3.RELEASE</version>
        </dependency>
        </dependencies>

    </project>

3.2 application.yml ファイルの構成

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/whisper?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  rabbitmq:
    host: 127.0.0.1
    username: test
    port: 5672
    virtual-host: /whhx
    password: 123456

server:
  port: 9999
mybatis:
  mapper-locations:
    - classpath:/mapper/*.xml
wx:
  app-id: wxaa64d0c144ca81b5
  app-secret: fcb7b645ecb419b5e55868706dd842d5
  token-url: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s
  message-url: https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s

management:
  health:
    rabbit:
      enabled: false

3.3 新しい MqSendMsgConfig 構成クラスの作成

package com.xxx.config;

import com.xxx.constant.QueueConstant;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MqSendMsgConfig {

    // 微信消息队列
    @Bean
    public Queue sendWxQueue(){
        return new Queue(QueueConstant.WX_SEND_QUEUE);
    }

    @Bean
    public DirectExchange sendWxEx(){
        return new DirectExchange(QueueConstant.WX_SEND_EX);
    }

    @Bean
    public Binding sendWxBind(){
        return BindingBuilder.bind(sendWxQueue()).to(sendWxEx()).with(QueueConstant.WX_SEND_KEY);
    }
}

3.4 新しい WxAutoConfiguration 構成クラスを作成する

package com.xxx.config;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;

@Configuration
@EnableConfigurationProperties(value = WxProperties.class)
@Slf4j
public class WxAutoConfiguration {

    @Autowired
    private RestTemplate restTemplate;

    private String wxAccessToken;

    /**
     * spring实现注解规范:方法在所有的Bean对象创建之后, 项目启动完成之前执行
     * 限制:不能有返回值,也不能有参数
     */
    @PostConstruct
    public void tokenInit(){
        getAccessToken();
    }

    @Scheduled(initialDelay = 0, fixedRate = 7100 * 1000)
    public void getAccessToken(){
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", "wxaa64d0c144ca81b5", "d81bb0ef2dc54f1754e7d2eef91df3f1");
        String accessTokenJsonStr = restTemplate.getForObject(url, String.class);
        JSONObject accessTokenJson = JSONObject.parseObject(accessTokenJsonStr);
        String accessToken = accessTokenJson.getString("access_token");
        if (!StringUtils.isEmpty(accessToken)){
            wxAccessToken = accessToken;
        }else {
            log.error("获取access_token失败");
        }

    }

    public String getWxAccessToken() {
        return wxAccessToken;
    }

    public void setWxAccessToken(String wxAccessToken) {
        this.wxAccessToken = wxAccessToken;
    }

}

3.5 新しい WxProperties 構成クラスを作成する

package com.xxx.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "wx")
public class WxProperties {

    private String appID;

    private String appSecret;

    private String accessTokenUrl;

    private String sendMsgUrl;

}

3.6 新しい QueueConstant インターフェイスの作成

package com.xxx.constant;

public interface QueueConstant {

    /**
     * 发送微信消息的队列
     */
    String WX_SEND_QUEUE = "wx.send.queue";

    /**
     * 发送微信消息的交换机
     */
    String WX_SEND_EX = "wx.send.ex";

    /**
     * 发送微信消息的路由key
     */
    String WX_SEND_KEY = "wx.send.key";

}

3.7 新しいコントローラーの作成

  @PostMapping("p/sms/sendWxMsg")
    public ResponseEntity<Void> sendWxMsg(@RequestBody OpenIdName openIdName){
        userService.sendWxMsg(openIdName.getOpenId(), openIdName.getUserName());
        return ResponseEntity.ok().build();

    }

3.8 新しい OpenIdName クラスの作成

package com.xxx.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class OpenIdName {

    private String openId;

    private String userName;
}

3.9 新しいサービス実装クラスの作成

package com.xxx.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxx.constant.QueueConstant;
import com.xxx.entity.User;
import com.xxx.mapper.UserMapper;
import com.xxx.model.WxMsgModel;
import com.xxx.service.UserService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

 
    /**
     * 发送微信消息
     *
     * @param openId
     * @param name
     */
    @Override
    public void sendWxMsg(String openId, String name) {
        WxMsgModel wxMsgModel = new WxMsgModel();
        wxMsgModel.setToUser(openId);
        wxMsgModel.setTemplateId("ByimXumDgKGmfDlqGPA2kgYCQK36hqGZy8e5KkCU2Dg");
        wxMsgModel.setUrl("https://www.baidu.com");
        wxMsgModel.setTopColor("#FF0000");

        HashMap<String, Map<String, String>> data = new HashMap<>();
        data.put("userName", WxMsgModel.buildMap(name, "#173177"));
        data.put("time", WxMsgModel.buildMap(new Date().toString(), "173177"));
        data.put("product", WxMsgModel.buildMap("女朋友", "173177"));
        data.put("money", WxMsgModel.buildMap("0.1", "173177"));
        wxMsgModel.setData(data);

        //用mq发送消息
        rabbitTemplate.convertAndSend(QueueConstant.WX_SEND_EX, QueueConstant.WX_SEND_KEY, JSON.toJSONString(wxMsgModel));
    }
}

3.10 新しいサービスインターフェースの作成


    /**
     * 发送微信消息
     * @param openId
     * @param name
     */
    void sendWxMsg(String openId, String name);

3.11 新しい WxMsgModel クラスの作成

package com.xxx.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.HashMap;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class WxMsgModel {

    // 注意使用的@JsonProperty
    @JsonProperty(value = "touser")
    private String toUser;

    @JsonProperty(value = "template_id")
    private String templateId;

    @JsonProperty(value = "url")
    private String url;

    @JsonProperty(value = "topcolor")
    private String topColor;

    @JsonProperty(value = "data")
    private Map<String, Map<String, String>> data;

    public static Map<String, String> buildMap(String value, String color){
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("value", value);
        hashMap.put("color", color);
        return hashMap;
    }
}

3.12 新しいリスナーの作成

package com.xxx.listener;

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import com.xxx.config.WxAutoConfiguration;
import com.xxx.config.WxProperties;
import com.xxx.constant.QueueConstant;
import com.xxx.model.WxMsgModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
@Slf4j
public class WxListener {

    @Autowired
    private WxProperties wxProperties;

    @Autowired
    private WxAutoConfiguration wxAutoConfiguration;

    @Autowired
    private RestTemplate restTemplate;



    /**
     * 处理微信公众号消息
     */
    @RabbitListener(queues = QueueConstant.WX_SEND_QUEUE, concurrency = "3-5")
    public void wxHandler(Message message, Channel channel){
        String msgStr = new String(message.getBody());
        WxMsgModel wxMsgModel = JSONObject.parseObject(msgStr, WxMsgModel.class);
        try {
            String response = sendWxMsg(wxMsgModel);
            log.info("发送微信公众号消息成功");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

        } catch (Exception e){
            log.error("发送微信公众号消息失败");
        }
    }

    /**
     * 发送微信消息
     */
    private String sendWxMsg(WxMsgModel wxMsgModel){
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
        String wxAccessToken = wxAutoConfiguration.getWxAccessToken();
        String url = String.format(accessTokenUrl, wxAccessToken);
        return restTemplate.postForObject(url, wxMsgModel, String.class);
    }
}


3.13 スタートアップクラス

package com.xxx;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@MapperScan(basePackages = "com.xxx.mapper")
@EnableScheduling
public class WhisperServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(WhisperServiceApplication.class,args);
    }

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

4. プロジェクトの全体像 (ユーザー関連のものは無視して構いません)

このプロジェクトは引き続きデモで開発されており、ユーザー関連の側面は無視してかまいません。
画像の説明を追加してください

5.rabbitmqのページ

ページ入力URL: http://localhost:15672
ログインアカウントのパスワード: guest

5.1 プロジェクト開始時に発生する可能性のある問題

1、An unexpected connection driver error occured
2、Restarting Consumer@43f3c557: tags=[[]], channel=null, acknowledgeMode=AUTO

待ってください。どのような問題が発生しても、mq に関連する問題は通常、mq に接続できないことです。現時点では、ページで新しいテスト アカウントを作成する必要があります。リンク: https://blog
. csdn.net/theRengar/article/details/ 118933418。とてもシンプル

6. プロジェクト立ち上げテスト

デバッグを使用してテストできます。メッセージが送信されると、リスナーはすぐにメッセージを取得して消費します。画像の説明を追加してください

画像の説明を追加してください
画像の説明を追加してください
画像の説明を追加してください

おすすめ

転載: blog.csdn.net/qq_36151389/article/details/132982846