导入maven依赖

<dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.15</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

通过查看微信模板消息文档发现

发送模板消息需要的json数据

{
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "miniprogram":{
             "appid":"xiaochengxuappid12345",
             "pagepath":"index?foo=bar"
           },          
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keyword1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keyword2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keyword3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }

模板实例

在这里插入图片描述

包含多种数据类型,并且以json数据格式请求接口便可以发送模板消息,发送成功效果。

在这里插入图片描述

我们看到first中的value对应的第一部分需要填充{{first.DATA}}占位符的数据,color对应字体的颜色keyword可能包含一个或者多个,所以我们需要动态创建,根据模板中的消息提供。remark填充最后一条数据

我们先创建六个实体类,对应模板消息用到的数据类型。

实体类代码

Remark

存储remark中的数据与颜色

package cn.xjt.wx.MessageEntity;


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


@Data
@AllArgsConstructor
@NoArgsConstructor
public class Remark {

    private String value;
    private String color;
}

Miniprogram //小程序相关数据,无小程序可以不填,或者填充空串

package cn.xjt.wx.MessageEntity;


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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Miniprogram {

    private String appid;
    private String pagepath;

}

Keyword,中间keyword部分

package cn.xjt.wx.MessageEntity;


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


@Data
@AllArgsConstructor
@NoArgsConstructor
public class Keyword {

    private String value;
    private String color;
}

First 首个数据

package cn.xjt.wx.MessageEntity;

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

import java.util.Date;

/**
 * @author xu
 * @Description
 * @createTime 2021年04月02日 17:02:00
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
public class First {

    private String value;
    private String color;

}

data 包含first、keyword、remark

由于keyword不固定,所以我在实体类创建多个提供使用,根据需要,构造需要个数

package cn.xjt.wx.MessageEntity;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.util.List;

@lombok.Data
@AllArgsConstructor
@NoArgsConstructor
public class data {

    private First first;

    private Keyword keyword1;
    private Keyword keyword2;
    private Keyword keyword3;
    private Keyword keyword4;
    private Keyword keyword5;
    private Remark remark;


    public data(First first,Remark remark,Keyword ... keyword){
        this.first=first;
        int count=1;
        for (Keyword keyword1 : keyword) {
            if (count==1){
                this.keyword1=keyword1;
            }else if (count==2){
                this.keyword2=keyword1;
            }else if (count==3){
                this.keyword3=keyword1;
            }else if (count==4){
                this.keyword4=keyword1;
            }else if (count==5){
                this.keyword5=keyword1;
            }
            count++;
        }
        this.remark=remark;
    }

}

JsonRootBean ,整合实体类所有数据

package cn.xjt.wx.MessageEntity;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class JsonRootBean {

    private String touser;
    private String template_id;
    private String url;
    private Miniprogram miniprogram;
    private data data;

}

实体类创建完成,所以当我们需要发送模板消息的时候,我们只需要一个JsonRootBean对象,就可以完成发送。

由于我在data实体类中的keyword只有五个,所以适用的模板消息中keyword最多只能有5个,跟一根据需要,酌情添加

发送模板消息用到的工具类

发送消息工具类

private static String grantType="client_credential";  

private static String appid="你的微信公众号appid";

private static String secret="你的开发者密码appsercet";

 public static Map<String,String> sendMessage2(String AccessToken, JsonRootBean jsonRootBean){
        JSONObject json = (JSONObject) JSON.parseObject(JSON.toJSONString(jsonRootBean));       //把JsonRootBean转成JSONObject对象
        String info = HttpUtil.sendPostJson(json, "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + AccessToken);
        Map<String,String> map = (Map) JSON.parse(info);
        System.out.println(map);
        return map;
    }

(携带json格式数据发送post请求工具类),请前往我的另一篇HttpUtil工具类获取

HttpUtil发送post携带Json数据工具类传送门

获取access_token (注意access_token有效期为两小时,过期后需重新获取)

public static Map<String,String> getAccessToken(){
        String s = HttpUtil.sendGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grantType + "&appid=" + appid + "&secret=" + secret);
        Map<String,String> map = (Map) JSON.parse(s);
        System.out.println(map);
        return map;
    }

发送模板案例

Miniprogram miniprogram = new Miniprogram("", "");
		First first = new First("你在虚拟仿真系统有一笔消息待处理", "");
		Keyword[] keywords = new Keyword[5];
		Keyword keyword1 = new Keyword("测试名称", "#173177");
		Keyword keyword2 = new Keyword("考试评价", "#173177");
		Keyword keyword3 = new Keyword(LocalDateTime.now().toString(), "#173177");
		Keyword keyword4 = new Keyword("考试成绩评分", "#173177");

		keywords[0] = keyword1;
		keywords[1] = keyword2;
		keywords[2] = keyword3;
		keywords[3] = keyword4;
		
		Remark remark = new Remark("请及时前往处理", "");
//		data data = new data(first, remark, keyword1, keyword2, keyword3, keyword4);
		data data = new data(first, remark, keywords);
		JsonRootBean jsonRootBean = new JsonRootBean("发个用户的openid", "你在微信公众号绑定的模板消息id", "单击模板会跳转的链接(https://www.baidu.com/实例)", miniprogram, data);
		WeiXinUtil.sendMessage2(WeiXinUtil.getAccessToken().get("access_token"), jsonRootBean);

效果

在这里插入图片描述

发送成功了!!

通过前端发送接受一个map数据类型的参数,发送模板消息,方法体????

/**
     * 动态接受参数发送消息
     * @param param
     */
    public static Map<String,String> sendMessagetop(Map<String,Object> param){
        Map<String,String> res = new HashMap<>();
        String accessToken = WeiXinUtil.getAccessToken();		//通过工具类方法获取accesstoken
        Miniprogram miniprogram=null;
        String firstColor=null;
        String remarkColor=null;
        if (param.get("appid")!=null && param.get("pagepath")!=null){
            miniprogram = new Miniprogram(param.get("appid").toString(), param.get("pagepath").toString());		//如果appid和pagepath都不为空,才进行初始化
        }
        String firstValue = param.get("firstValue").toString();		//获取firstvalue
        if (param.get("firstColor")!=null){
            firstColor = param.get("firstColor").toString();		//如果颜色不为空,则获取
        }
        First first = new First(firstValue, firstColor);
        Integer keywordCount = Integer.valueOf(param.get("keywordCount").toString());		//得到有几个keyword
        Keyword[] keywords = new Keyword[5];
        for (int i=0;i<keywordCount;i++){		//动态创建kewword
            Map kw = (Map) param.get(i+"");
            String color = null;
            if (kw.get("color")!=null){				//得到key对象里面的value与color
                color=kw.get("color").toString();		//如果color不为空,则获取
            }
            keywords[i]=new Keyword(kw.get("value").toString(), color);
        }
        String remarkValue = param.get("remarkValue").toString();
        if (param.get("remarkColor")!=null){
            remarkColor = param.get("remarkColor").toString();
        }
        Remark remark = new Remark(remarkValue, remarkColor);
        data data = new data(first, remark, keywords);		
        Map<String, Object> allOpenId = WeiXinUtil.getAllOpenId();		//获取关注公众号的所有openid
        Map datas = (Map) allOpenId.get("data");
        List<String> openid = (List) datas.get("openid");//得到openid数组
        for (String o : openid) {		//遍历依次发送模板消息
            System.out.println(o);
            JsonRootBean jsonRootBean = new JsonRootBean(o, TEMPLATE_ID, URL, miniprogram, data);
            Map<String, String> result = WeiXinUtil.sendMessage2(accessToken, jsonRootBean);
            res.put("errmsg", result.get("errmsg"));
        }
        return res;
    }

以上是给所有关注了该公众号的用户都发送消息

到此这篇关于教你用java完美封装微信模板消息的发送动态的文章就介绍到这了,更多相关java封装微信消息的发送内容请搜索程序员的世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员的世界!

java完美封装微信模板消息的发送动态的更多相关文章

  1. Java下载远程服务器文件到本地(http协议和ssh2协议)

    Java中java.io包为我们提供了输入流和输出流,对文件的读写基本上都依赖于这些封装好的关于流的类中来实现。前段时间遇到了以下两种需求:1、与某系统对接,每天获取最新的图片并显示在前端页面。该系统提供的是一个http协议的图片URL,本来获取到该系统的图片地址以后在HTML中显示就可以了,但是该......

  2. Java多线程总结(二)

    四.Java多线程的阻塞状态与线程控制上文已经提到Java阻塞的几种具体类型。下面分别看下引起Java线程阻塞的主要方法。1.join()join —— 让一个线程等待另一个线程完成才继续执行。如A线程线程执行体中调用B线程的join()方法,则A线程被阻塞,知道B线程执行完为止,A才能得以继续执行......

  3. java读取证书公钥的实现

    方式1:使用javax.security.cert.X509Certificate进行解析URL url = Demo.class.getClassLoader().getResource("C000024.crt"); //证书路径System.out.println(&qu......

  4. Java如何实现单链表的增删改查

    一、新建学生节点类Stu_Node节点包含:学号:int num;姓名:String name;性别:String gender;下一个节点:Stu_Node next;为了便于打印节点内容需要重写toString方法class Stu_Node{int num;String name;String......

  5. java ArrayBlockingQueue的方法及缺点分析

    提到ArrayBlockingQueue的方法,想必大家都不陌生,我们在入队和出队的时候,接触了不少这方面的函数。当然ArrayBlockingQueue中的方法也不止于此,今天我们就全部为大家罗列出来,也算是做一个学习方向上的指引。然后就其中的peek方法带来实例介绍,并说明ArrayBlocki......

  6. Java使用Sftp和Ftp实现对文件的上传和下载

    sftp和ftp两种方式区别,还不清楚的,请自行百度查询,此处不多赘述。完整代码地址在结尾!!第一步,导入maven依赖<!-- FTP依赖包 --><dependency><groupId>commons-net</groupId><artif......

  7. java 最新Xss攻击与防护(全方位360°详解)

    前沿XSS防范属于前端还是后端的责任 ?XSS 防范是后端 RD(研发人员)的责任,后端 RD 应该在所有用户提交数据的接口,对敏感字符进行转义,才能进行下一步操作。所有要插入到页面上的数据,都要通过一个敏感字符过滤函数的转义,过滤掉通用的敏感字符后,就可以插入到页面中。公司的搜索页面如果你是下面的......

  8. java中fork-join的原理解析

    ForkJoinTask就是ForkJoinPool里面的每一个任务。他主要有两个子类:RecursiveAction和RecursiveTask。然后通过fork()方法去分配任务执行任务,通过join()方法汇总任务结果,这就是整个过程的运用。他有两个子类,使用这两个子类都可以实现我们的任务分配......

  9. Java中ArrayList初始化的四种方法详解

    1 起因在实际业务开发中, 我们经常会遇到需要临时创建一个数组的情况, 今天我们就来讲一下Java中ArrayList初始化的方法2 解决方案直接上结论, 总共有四种初始化方法:双括号法Arrays.asListstreamLists2.1 双括号法List<Integer> test ......

  10. 深入浅出Java线程池:使用篇

    前言很高兴遇见你~借助于很多强大的框架,现在我们已经很少直接去管理线程,框架的内部都会为我们自动维护一个线程池。例如我们使用最多的okHttp以及他的封装框架Retrofit,线程封装框架RxJava和kotlin协程等等。为了更好地使用这些框架,则必须了解他的实现原理,而了解他的原理,线程池是永远......

随机推荐

  1. Linux core dump使用

    什么是 core dump?core dump是一个当进程意外终止时包含进程内存内容的文件。当程序崩溃的时候,core dump由kernel触发。core dump可以作为程序崩溃时的事后快照(post-mortem snapshot),尤其是在难以可靠的重现故障的情况下。大多数Linux系统默认......

  2. Python中的内部对象

    目录简介内置函数内置常量内置类型逻辑值检测逻辑值的布尔运算比较运算数字类型整数类型的位运算整数类型的附加方法浮点类型的附加方法迭代器序列类型集合类型映射类型字典视图对象内置异常简介Python中内置了很多非常有用的对象,本文将会介绍Python中的内置函数,内置常量,内置类型和内置异常。内置函数Py......

  3. C# Winform 实现控件自适应父容器大小的示例代码

    在日常开发中经常遇到控件不能随着父容器大小的改变而且自动改变控件的所在位置和大小。以下是实现的代码/// <summary>/// 根据父容器实现控件自适应大小位置/// </summary>/// <param name="control">......

  4. mysql按时间查询(年/月/日)

    0.创建表sql语句查询mysql> show create table byzp_personinfo;CREATE TABLE `byzp_personinfo` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varcha......

  5. 详解如何在ASP.NET Core Web API中以三种方式返回数据

    在 ASP.NET Core 中有三种返回 数据 和 HTTP状态码 的方式,最简单的就是直接返回指定的类型实例,如下代码所示:[ApiController][Route("[controller]")]public class WeatherForecastController......

  6. Room Kotlin API的使用入门教程

    Room 是 SQLite 的封装,它使 Android 对数据库的操作变得非常简单,也是迄今为止我最喜欢的 Jetpack 库。在本文中我会告诉大家如何使用并且测试 Room Kotlin API,同时在介绍过程中,我也会为大家分享其工作原理。我们将基于 Room with a view code......

  7. Redis Sentinel的基本搭建

    Redis Sentinel的概念 我们知道Redis主从模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点的地址。然后在很多应用场景下这种故障处理的方式是无法接受的,应用程序需要实时感知当前的可用节点。为了解决这个问题,Redis Sen......

  8. python 使用Yolact训练自己的数据集

    可能是由于yolact官方更新过其项目代码,所以网上其他人的yolact训练使用的config文件和我的稍微有区别。但总体还是差不多的。1:提前准备好自己的数据集使用labelme来制作分割数据集,但是得到的是一个个单独的json文件。需要将其转换成coco。labelme2coco.py如下所示(......

  9. C# 两个类的实例之间相同属性的值的复制

    在进行实体转换操作的时候通常需要在对两个实体之间两个属性字段相同的类要进行一个互相的转换,我们要把a对象的所有字段的值都复制给b对象,我们只能用b.属性=a.属性来写,如果属性字段太多的话,就要写很多行复制语句,并且还容易漏掉一些,这个时候可以利用c#的反射来实现复制。1.适用于创建实体的时候从一个......

  10. 使用 C# 9 的records作为强类型ID - JSON序列化

    在本系列的上一篇文章中,我们注意到强类型ID的实体,序列化为 JSON 的时候报错了,就像这样:{"id": {"value": 1},"name": "Apple","unitPrice": 0.8......