阅读量:0
小程序订阅消息(用户通过弹窗订阅)开发指南 | 微信开放文档 (qq.com)
一. 在小程序后台申请模板获得模板ID
二.相关代码
2.1 编写相关实体类
2.1.1 详细内容类
@Data @AllArgsConstructor @NoArgsConstructor public class DataClaimVO { private Map<String,String> thing4; private Map<String,String> name2; private Map<String,String> phone_number3; private Map<String, LocalDate> time5; }
2.1.2 通知订阅类
此处根据自己的实际业务书写,有多个模板就需要使用泛型
一个模板直接用final即可
@Data public class WxInfoVO<T> { /** * 用户openid */ private String touser; /** * 模版id */ private String template_id; /** * 默认 */ private static final String page = "pages/index/index"; /** * "data": { * "thing1": "身份证", * "name2": "风清默", * "phone_number4": "113132", * "date3": "2024-4-25" * }, */ private T data; /** * 转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 */ private static final String miniprogram_state = "developer"; private static final String lang = "zh_CN"; //category 0 :物品找回通知 通知失主 1:失物认领通知 通知发布(捡到的人) public WxInfoVO(String touser, Boolean category, T dataVO) { this.touser = touser; this.template_id = (!category ? 模板1id : 模板2id); this.data = dataVO; } }
2.1.3 小程序配置类
@Component @ConfigurationProperties(prefix = "xunhang.wechat.wxinfo") @Data public class WeChatProperties { private String appid; //小程序的appid private String secret; //小程序的秘钥 private String mchid; //商户号 private String mchSerialNo; //商户API证书的证书序列号 private String privateKeyFilePath; //商户私钥文件 private String apiV3Key; //证书解密的密钥 private String weChatPayCertFilePath; //平台证书 private String notifyUrl; //支付成功的回调地址 private String refundNotifyUrl; //退款成功的回调地址 }
2.2 相关工具类
2.2.1 http请求类
public class HttpClientUtil { static final int TIMEOUT_MSEC = 5 * 1000; /** * 发送GET方式请求 * @param url * @param paramMap * @return */ public static String doGet(String url,Map<String,String> paramMap){ // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); String result = ""; CloseableHttpResponse response = null; try{ URIBuilder builder = new URIBuilder(url); if(paramMap != null){ for (String key : paramMap.keySet()) { builder.addParameter(key,paramMap.get(key)); } } URI uri = builder.build(); //创建GET请求 HttpGet httpGet = new HttpGet(uri); //发送请求 response = httpClient.execute(httpGet); //判断响应状态 if(response.getStatusLine().getStatusCode() == 200){ result = EntityUtils.toString(response.getEntity(),"UTF-8"); } }catch (Exception e){ e.printStackTrace(); }finally { try { response.close(); httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } return result; } /** * 发送POST方式请求 * @param url * @param paramMap * @return * @throws IOException */ public static String doPost(String url, Map<String, String> paramMap) throws IOException { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); // 创建参数列表 if (paramMap != null) { List<NameValuePair> paramList = new ArrayList(); for (Map.Entry<String, String> param : paramMap.entrySet()) { paramList.add(new BasicNameValuePair(param.getKey(), param.getValue())); } // 模拟表单 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList); httpPost.setEntity(entity); } httpPost.setConfig(builderRequestConfig()); // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } catch (Exception e) { throw e; } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } /** * 发送POST方式请求 * @param url * @param paramMap * @return * @throws IOException */ public static<T> String doPostByJson(String url, T object) throws IOException { // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); if (object != null) { //构造json格式数据 // 将对象转换为JSON字符串 ObjectMapper objectMapper = new ObjectMapper(); String jsonStr= JSONUtil.toJsonStr(object); StringEntity entity = new StringEntity(jsonStr,"utf-8"); //设置请求编码 entity.setContentEncoding("utf-8"); //设置数据类型 entity.setContentType("application/json"); httpPost.setEntity(entity); } httpPost.setConfig(builderRequestConfig()); // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } catch (Exception e) { throw e; } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } return resultString; } private static RequestConfig builderRequestConfig() { return RequestConfig.custom() .setConnectTimeout(TIMEOUT_MSEC) .setConnectionRequestTimeout(TIMEOUT_MSEC) .setSocketTimeout(TIMEOUT_MSEC).build(); } }
2.2.2 微信功能类(核心)
这里我使用了 Redis 存储 accessToken
@Component public class WxUtil { @Autowired private WeChatProperties weChatProperties; @Autowired private StringRedisTemplate stringRedisTemplate; public void getAccessToken() { String appid = weChatProperties.getAppid(); String secret = weChatProperties.getSecret(); String grant_type = "client_credential"; Map<String, String> map = new HashMap<String, String>(); map.put("appid", appid); map.put("secret", secret); map.put("grant_type", grant_type); String json = HttpClientUtil.doGet(WX_ACCESS_TOKEN_URL, map); JSONObject jsonObject = JSONObject.parseObject(json); Integer errcode = jsonObject.getInteger("errcode"); if (errcode == null || errcode == 0) { String accessToken = jsonObject.getString("access_token"); Integer expiresIn = jsonObject.getInteger("expires_in"); stringRedisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken, expiresIn, TimeUnit.SECONDS); } else { throw new WxServiceException("调用accessToken失败"); } } public String sendSubscribeInfo(WxInfoVO wxInfoVO) throws InterruptedException, IOException { String token = stringRedisTemplate.opsForValue().get(ACCESS_TOKEN_KEY); if (token == null) { getAccessToken(); } Integer t = 0; while (token == null && t < 10) { token = stringRedisTemplate.opsForValue().get(ACCESS_TOKEN_KEY); t++; Thread.sleep(100); } if (token == null) { throw new WxServiceException("获取不到accessToken"); } String json = HttpClientUtil.doPostByJson(WX_SEND_SUBSCRIBE_URL + "?access_token=" + token,wxInfoVO); return json; } }
2.3 相关依赖
<!--redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--redis连接池--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!-- lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- hutoo--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.5.15</version> </dependency> <!--fastJSON--> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.40</version> </dependency>
三.执行
@SpringBootTest public class WxinfoApplicationTests { @Autowired WxUtil wxUtil; @Test public void test() throws IOException, InterruptedException { Map<String, String> thing1 = new HashMap<>(); thing1.put("value","身份证"); Map<String, String> name2 = new HashMap<>(); name2.put("value","风清默"); Map<String, String> phone_number4 = new HashMap<>(); phone_number4.put("value","1199293"); Map<String, LocalDateTime> date3 = new HashMap<>(); date3.put("value",LocalDateTime.now()); DatafoundVO dataVO = new DatafoundVO(thing1, name2, phone_number4,date3); WxInfoVO wxInfoVO = new WxInfoVO(用户openid,false,dataVO); // System.out.println(JSONUtil.toJsonStr(wxInfoVO)); System.out.println(wxUtil.sendSubscribeInfo(wxInfoVO)); } }
成功