申请注册账号
第一步:首先你需要在微信公众平台 (qq.com)注册一个小程序个人测试账号,然后在首页发布一个小程序成功后如图:
然后就会产生一个小程序的appId和密钥,这两个东西是产生AccessToken和openId的关键点击开发中的开发管理,然后如图查看自己小程序的appId和密钥,密钥的话重置一下就看到了:
第二步:点击你的订阅消息然后里面有添加模板然然后根据自己的业务需求添加模板或者使用现成的模板就可以产生一模板ID这这个ID发送消息的时候需要,如图:
Java后端发送
第三步:后端代码附上:
myHttpRequesUtil是微信发送工具
package com.longdatech.decryptcode.utils;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
/**
* @author: qiaolu
* @date 2023/4/7 12:51
*/
public class MyHttpRequestUtil {
/**
* 向指定URL发送GET方法的请求
*
* @param url 发送请求的URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
System.out.println(realUrl);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
/* for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}*/
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* @description
* @author: qiaolu
* @date 2023/4/7 12:51
* @param url
* @return
*/
public static String sendGet(String url) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url;
URL realUrl = new URL(urlNameString);
System.out.println(realUrl);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
/* for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}*/
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
public static String getUserUathUrl(String appid, String redirectUrl) throws UnsupportedEncodingException {
StringBuffer getcodeUrl = new StringBuffer()
.append("https://open.weixin.qq.com/connect/oauth2/authorize")
.append("?appid=" + appid)
.append("&redirect_uri=" + URLEncoder.encode(redirectUrl, "utf-8"))
.append("&response_type=code")
.append("&scope=snsapi_userinfo")
.append("&state=" + System.currentTimeMillis())
.append("#wechat_redirect");
return getcodeUrl.toString();
}
}
WxVo类是根据微信api模板消息发送需要参数的实体类
package com.longdatech.decryptcode.utils;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* @author qiaolu
* @date 2023/4/7 12:51
*/
@Data
public class WxVo {
private String touser;
private String template_id;
private String page;
private String access_token;
private String request_url;
private String miniprogram_stat;
private String lang;
private JSONObject data;
}
package com.longdatech.decryptcode.utils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
/**
* @author qiaolu
* @date 2023/4/7 12:51
*/
@Slf4j(topic = "WxchatSendUtil")
@Component
public class WxchatSendUtil {
// @Value("${bussiness.appId}")
private static String appId = "你自己的appId";
// @Value("${bussiness.secret}")
private static String secret = "你自己的密钥";
// @Value("${bussiness.orderPlacementNoticeTemplateId}")
private static String orderPlacementNoticeTemplateId = "你自己的模板Id";
/**
* 获取小程序token
*
* @return
*/
public static String getAccessToken() {
String url = "https://api.weixin.qq.com/cgi-bin/token?" +
"appid=" + appId + "&secret=" + secret + "&grant_type=client_credential";
PrintWriter out = null;
BufferedReader in = null;
String line;
StringBuffer stringBuffer = new StringBuffer();
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性 设置请求格式
//设置返回类型
conn.setRequestProperty("contentType", "text/plain");
//设置请求类型
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
//设置超时时间
conn.setConnectTimeout(1000);
conn.setReadTimeout(1000);
conn.setDoOutput(true);
conn.connect();
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应 设置接收格式
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((line = in.readLine()) != null) {
stringBuffer.append(line);
}
JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
return jsonObject.getString("access_token");
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
public static final String SEND_INFO_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
public static void main(String[] args) throws IOException {
// 1、获取 接口调用凭证
RestTemplate restTemplate = new RestTemplate();
String url = SEND_INFO_URL + WxchatSendUtil.getAccessToken();
System.out.println("s:" + WxchatSendUtil.getAccessToken());
//拼接推送的模版
WxVo wxMssVo = new WxVo();
//用户的openId
wxMssVo.setTouser("osCmN4mokDtVkfcipnhaRC1J3_qY");
//订阅消息模板id
wxMssVo.setTemplate_id(orderPlacementNoticeTemplateId);
wxMssVo.setPage("index");
wxMssVo.setMiniprogram_stat("developer");
wxMssVo.setLang("zh_CN");
JSONObject m = new JSONObject();
JSONObject object1 = new JSONObject();
JSONObject object2 = new JSONObject();
JSONObject object3 = new JSONObject();
JSONObject object4 = new JSONObject();
//下面的key是固定的就是"value"自己看接口api然后下面的val值就是发送的内容
object1.put("value", "154956559599");
object2.put("value", "eri0g9i9");
object3.put("value", "30");
object4.put("value", "30");
//自己看自己小程序中生成的模板参数然后然后替换我写的key值
m.put("number2", object1);
m.put("thing1", object2);
m.put("amount3", object3);
m.put("amount4", object4);
wxMssVo.setData(m);
MyHttpRequestUtil.sendPost(url, JSONObject.toJSONString(wxMssVo));
System.out.println(MyHttpRequestUtil.sendPost(url, JSONObject.toJSONString(wxMssVo)));
}
}
到此返回的对象中code为0就是发送成功。
自己手机测试
如果想在自己手机上测试那就必须要下载微信开发工具:微信开放文档如图:
使用微信开发工具登录自己在注册的小程序账号然后生成appjs中复制下面一段代码,不过要在代码中更改自己的模板Id,代码附上
// app.js
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
wx.showModal({
title: '提示',
content:'请授权开通服务通知',
showCancel: true,
success: function (ress) {
if (ress.confirm) {
// console.log('用户点击确定')
wx.requestSubscribeMessage({ // 调起消息订阅界面
tmplIds: ['自己的模板Id'],
success (res) {
console.log('订阅消息 成功 ');
console.log(res);
},
fail (er){
console.log("订阅消息 失败 ");
console.log(er);
}
})
} else if (ress.cancel) {
// console.log('用户点击取消')
}
}
})
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
console.log(res.code)
}
})
},
globalData: {
userInfo: null
}
})
然后你就消息订阅成功,然后代码会返回一个code值如图:
最后拿着你的code值去生成当前小程序的openId就可以返回上面发送代码进行发送,生成openId代码附上:
public String decryptCode(@RequestParam String code){
log.info("1.0:解密code===>code:" + code);
String result = MyHttpRequestUtil.sendGet(WxConstant.getDesryptCodeUri(code));
JSONObject ojb = JSONObject.parseObject(result);
System.out.println("返回结果:" + ojb);
Set<String> keys = ojb.keySet();
keys.forEach(item->{
System.out.println(item + ":" + ojb.get(item));
});
System.out.println(ojb.getString("openid"));
return ojb.getString("openid");
}
就可以如图收到消息: