赞
踩
最近做个排号叫号的微信小程序,想用户在微信小程序上进行排号,商家在小程序上进行叫号,叫号的通知发送到用户微信里.这里就要用到订阅消息.
登录微信公众平台
创建一个自己需要的模版,具体创建请自行查阅,今天的重点不在这里…
用户的openid的获取,我是在用户使用微信登录时进行获取的,具体可以查看我微信登录的文章:传送门
我们首先来看看access_token是什么,官方的说明是:
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
简单来说,access_token就是小程序官方给我们提供的一个凭证,如果要调用官方的接口,就必须先获取凭证,所以我们先来谈谈怎么获取access_token.
还是先看官方文档
从官方文档我们可以看到,我们需要以下几个参数
参数 | 是否必须 | 说明 |
---|---|---|
grant_type | 是 | 获取access_token填写client_credential |
appid | 是 | 第三方用户唯一凭证 |
secret | 是 | 第三方用户唯一凭证密钥,即appsecret |
grant_type是一个固定的值,appid和secret是需要我们填入的,这两个值在我们的小程序后台就可以拿到,具体可以查看我微信登录的文章:传送门
可以在微信小程序后台去寻找appid和secret
具体思路就是先向微信提供的这个url发送一个get请求.
微信官方给的正常返回值为
新建一个pojo来存储返回的参数
import lombok.Data;
/**
* @author zty
* @date 2020/4/23 下午2:26
* @description:
*/
@Data
public class getAccessTokenModel {
private String access_token;
private Integer expires_in;
}
然后利用一个http工具类发送请求,一个json转model工具类来转换一下.这两个工具类具体代码后面贴出
这就是我们获取access_token的代码了,获取之后将他存入redis,设置有效时间,超时就重新获取.
/** * 获取AccessToken * * @return */ public String getAccessToken() { if (redisUtil.get("access_token") != null) { return (String) redisUtil.get("access_token"); } //GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET String url = "https://api.weixin.qq.com/cgi-bin/token"; Map<String, String> param = new HashMap<>(); param.put("grant_type", "client_credential"); param.put("appid", "wx7e139fc4dec9fd08"); param.put("secret", "d483c36cf9f93500a17aa0cb788a0f48"); String vxResult = HttpClientUtil.doGet(url, param); log.info(vxResult); getAccessTokenModel accessTokenModel = JsonUtils.jsonToPojo(vxResult, getAccessTokenModel.class); redisUtil.set("access_token", accessTokenModel.getAccess_token(), accessTokenModel.getExpires_in()); return accessTokenModel.getAccess_token(); //POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN }
使用这两个工具类需要引入俩个maven依赖
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
package com.vx.utils; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; /** * @author zty */ public class HttpClientUtil { public static String doGet(String url, Map<String, String> param) { // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { // 创建uri URIBuilder builder = new URIBuilder(url); if (param != null) { for (String key : param.keySet()) { builder.addParameter(key, param.get(key)); } } URI uri = builder.build(); // 创建http GET请求 HttpGet httpGet = new HttpGet(uri); // 执行请求 response = httpclient.execute(httpGet); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (response != null) { response.close(); } httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } public static String doGet(String url) { return doGet(url, null); } public static String doPost(String url, Map<String, String> param) { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); // 创建参数列表 if (param != null) { List<NameValuePair> paramList = new ArrayList<>(); for (String key : param.keySet()) { paramList.add(new BasicNameValuePair(key, param.get(key))); } // 模拟表单 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList); httpPost.setEntity(entity); } // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } public static String doPost(String url) { return doPost(url, null); } public static String doPostJson(String url, String json) { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); // 创建请求内容 StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); httpPost.setEntity(entity); // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } }
package com.vx.utils; import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; /** * * @Title: JsonUtils.java * @Package com.lee.utils * @Description: 自定义响应结构, 转换类 * Copyright: Copyright (c) 2016 * Company:Nathan.Lee.Salvatore * * @author zty * @date 2020年4月15日 下午11:05:03 * @version V1.0 */ public class JsonUtils { // 定义jackson对象 private static final ObjectMapper MAPPER = new ObjectMapper(); /** * 将对象转换成json字符串。 * <p>Title: pojoToJson</p> * <p>Description: </p> * @param data * @return */ public static String objectToJson(Object data) { try { String string = MAPPER.writeValueAsString(data); return string; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * 将json结果集转化为对象 * * @param jsonData json数据 * @param clazz 对象中的object类型 * @return */ public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json数据转换成pojo对象list * <p>Title: jsonToList</p> * <p>Description: </p> * @param jsonData * @param beanType * @return */ public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List<T> list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); } return null; } }
好了,这样我我们就获取到了access_token,注意我是存在redis里的
小程序端获取授权我这里就不在介绍了,具体看微信的官方文档
我们通过上面第二步,成功的获取到了access_token。下面就要调用小程序官方为我们提供的发送消息的接口了,先看下官方文档。
上面有些参数是我们发送消息所需要的.
这里需要注意的是,我们要向用户发送订阅消息,小程序端就要去诱导用户授权
正常来说,一次授权只允许发送一条消息.
先创建一个类,注意Thing要与你模板对应
import lombok.AllArgsConstructor; import lombok.Data; /** * @author zty * @date 2020/4/23 下午8:31 * @description: */ @Data public class SubscribeMessageVO { //具体的订阅消息的key {{thing4.DATA}} 则key为thing4 private Thing4 thing4; private Thing6 thing6; private Thing7 thing7; @Data @AllArgsConstructor public static class Thing4{ private String value; } @Data @AllArgsConstructor public static class Thing6{ private String value; } @Data @AllArgsConstructor public static class Thing7{ private String value; } }
我这里发送用到了消息队列,可以忽略
/** * 发送订阅消息 * * @param peopleSet */ @RabbitListener(bindings = { @QueueBinding( value = @Queue,//创建临时队列 exchange = @Exchange(value = "updateHistory", type = "fanout") ) }) public void sendMessage(String peopleSet) { String[] temp; temp = peopleSet.split("\\+"); String p1 = temp[0]; Long p2 = Long.valueOf(temp[1]); Long p3 = Long.valueOf(temp[2]); ActivityUserHistory history = activityUserHistoryMapper.selectByOpenId2(getUserIdByOpenId(p1), p2, p3); SubscribeMessageVO bean = new SubscribeMessageVO(); bean.setThing4(new SubscribeMessageVO.Thing4(history.getActivityName() + ":" + history.getName())); bean.setThing6(new SubscribeMessageVO.Thing6(history.getAddress())); bean.setThing7(new SubscribeMessageVO.Thing7("请到服务处联系工作人员")); WxMssVO wxMssVO = new WxMssVO(); wxMssVO.setTouser(p1); wxMssVO.setTemplate_id("***");//模板id号码 wxMssVO.setData(bean); push(wxMssVO); } public void push(WxMssVO wxMssVO) { String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + getAccessToken(); String json = JsonUtils.objectToJson(wxMssVO); String vxResult = HttpClientUtil.doPostJson(url, json); log.info("返回的内容:" + vxResult); }
将信息加入SubscribeMessageVO这个类的一个对象中,然后转为json,继续调用我们刚刚的http工具类发送.这样就能得到我们开始时的订阅消息了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。