测试号管理:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
在开发之前需要做的事情:
1.申请一个公众号测试账号,一分钟就可以申请下来
2.然后需要一个微信验证token的地址,这个大家可以网上找一下 比较简单。
验证token的代码贴一下
package com.cjkj.message.controller;
import com.cjkj.message.utils.SignUtil;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* @program: cjkj
* @description:
* @author: Mr.Wang
* @create: 2020-03-25 17:11
**/
@Controller
@RequestMapping("/wechat")
public class WechatController {
private static Logger logger = Logger.getLogger(WechatController.class);
@RequestMapping(value = "security", method = RequestMethod.GET)
public void doGet(
HttpServletRequest request,
HttpServletResponse response,
@RequestParam(value = "signature", required = true) String signature,
@RequestParam(value = "timestamp", required = true) String timestamp,
@RequestParam(value = "nonce", required = true) String nonce,
@RequestParam(value = "echostr", required = true) String echostr) {
try {
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
PrintWriter out = response.getWriter();
out.print(echostr);
out.close();
} else {
logger.info("这里存在非法请求!");
}
} catch (Exception e) {
logger.error(e, e);
}
}
@RequestMapping(value = "security", method = RequestMethod.POST)
// post方法用于接收微信服务端消息
public void DoPost() {
System.out.println("这是post方法!");
}
}
3.token验证成功后,用自己的微信扫描关注公众号。


4.创建一个自定义的模板。
我的模板事这个:
| {{first.DATA}} 用户名:{{keyword1.DATA}} 订单号:{{keyword2.DATA}} 订单金额:{{keyword3.DATA}} 商品信息:{{keyword4.DATA}} {{remark.DATA}} 复制粘贴进去就可以了。
|
5.上边的话我们就可以看到appID,appsecret,关注用户的微信号,也就是openid。然后还有自己船舰的模板id(模板ID(用于接口调用))
接下来我们用代码就可以实现了。
我的代码中包含了一些业务代码,大家看的时候跳过。同时我们的appID,appsecret保存在数据库,当调用的时候 ,通过参数appkey去查询到这两个参数。
wechat: #获取token的地址 getTokenUrl: https://api.weixin.qq.com/cgi-bin/token #发送公众号消息的地址 sendMsgUrl: https://api.weixin.qq.com/cgi-bin/message/template/send #发送小程序的消息地址 sendMiniPUrl: https://api.weixin.qq.com/cgi-bin/message/subscribe/send
@RestController
@RequestMapping("/wechat")
public class WechatMessageController {
private static Logger logger = Logger.getLogger(WechatMessageController.class);
@Autowired
private WechatService wechatService;
/**
* 公众号发送模板消息
* @return
*/
@ApiOperation(value="公众号发送模板消息", notes="根据参数发送模板消息")
@ApiImplicitParams({
@ApiImplicitParam(name = "WechatTokenEntity", value = "公众号实体", required = true, paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "data", value = "模板信息参数json结构的字符串", required = true, paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "miniprogram", value = "小程序参数json结构字符串", required = true, paramType = "query", dataType = "String")
})
@RequestMapping(value="/sendMessage" ,method = {RequestMethod.POST})
public com.cjwl.ResultData sendMessage(HttpServletRequest request, WechatOfficialEntity wechatOfficialEntity, @RequestParam String data, @RequestParam String miniProgram) {
return wechatService.sendMsg(request, wechatOfficialEntity, data, miniProgram);
}
/**
* 小程序发送模板消息
* @return
*/
@ApiImplicitParams({
@ApiImplicitParam(name = "MiniProgramEntity", value = "小程序实体", required = true, paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "data", value = "发送信息参数json结构的字符串", required = true, paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "miniprogram", value = "小程序参数json结构字符串", required = true, paramType = "query", dataType = "String")
})
@RequestMapping(value="/sendMiniProgramMessage", method = {RequestMethod.POST})
public com.cjwl.ResultData miniPSendMessage(HttpServletRequest request, WechatMiniProgramEntity wechatMiniProgramEntity, @RequestParam String data) {
return wechatService.sendMiniProgramMsg(request, wechatMiniProgramEntity, data);
}
}
/**
* @program: cjkj
* @description:
* @author: Mr.Wang
* @create: 2020-03-31 00:10
**/
public interface WechatService {
public ResultData sendMsg (HttpServletRequest request, WechatOfficialEntity wechatOfficialEntity, String data, String miniprogram);
public ResultData sendMiniProgramMsg (HttpServletRequest request, WechatMiniProgramEntity wechatMiniProgramEntity, String data);
}
@Service
public class WechatServiceImpl implements WechatService {
private static Logger logger = Logger.getLogger(WechatServiceImpl.class);
@Autowired
private ApikeyWechatDao apikeyWechatDao;
@Value("${wechat.sendMiniPUrl}")
private String sendMiniPUrl;
@Value("${wechat.sendMsgUrl}")
private String sendMsgUrl;
@Value("${wechat.getTokenUrl}")
private String getTokenUrl;
@Override
public ResultData sendMsg(HttpServletRequest request, WechatOfficialEntity wechatOfficialEntity, String data, String miniprogram) {
//此处需要更换成appkey 替换appid和appsecret
if (StringUtils.isNotBlank(wechatOfficialEntity.getApikey())) {
if (stringRedisUtil.haskey(wechatOfficialEntity.getApikey())) {
wechatOfficialEntity.setToken(stringRedisUtil.getStrValue(wechatOfficialEntity.getApikey()).toString());
} else {
List<ApikeyWechatEntity> apikeyRelationEntities = apikeyWechatDao.listWechatApikeyInfo(wechatOfficialEntity.getApikey(), wechatOfficialEntity.getIdentity());
String wechatAppKey = apikeyRelationEntities.get(0).getWechatAppKey();
String wechatSecret = apikeyRelationEntities.get(0).getWechatSecret();
String token = WechatSendMsgUtil.getToken(wechatAppKey, wechatSecret, getTokenUrl);
wechatOfficialEntity.setToken(token);
stringRedisUtil.set(wechatOfficialEntity.getApikey(), token, 7000);//减少延迟带来的误差
}
}
//发送消息
String result = WechatSendMsgUtil.SendWeChatMsg(wechatOfficialEntity, sendMsgUrl, data, miniprogram);
logger.info("公众号发送结果:" + result);
JSONObject jsonResult = JSONObject.parseObject(result);
String errCode = jsonResult.getString("errcode");
String errMsg = jsonResult.getString("errmsg");
try {
final PushMessageEntity pushMessageEntity = getPushMessage(wechatOfficialEntity, data, miniprogram);
} catch (Exception ex) {
logger.error("解析IP地址失败!", ex);
ResultData.build("500", "服务解析错误");
}
return ResultData.build(errCode, errMsg,null);
}
/**
* 小程序发送消息
*
* @param wechatMiniProgramEntity
* @param data
* @return
*/
@Override
public ResultData sendMiniProgramMsg(HttpServletRequest request, WechatMiniProgramEntity wechatMiniProgramEntity, String data) {
if (StringUtils.isNotBlank(wechatMiniProgramEntity.getApikey())) {
if (stringRedisUtil.haskey(wechatMiniProgramEntity.getApikey())) {
wechatMiniProgramEntity.setToken(stringRedisUtil.getStrValue(wechatMiniProgramEntity.getApikey()).toString());
} else {
List<ApikeyWechatEntity> apikeyRelationEntities = apikeyWechatDao.listWechatApikeyInfo(wechatMiniProgramEntity.getApikey(), wechatMiniProgramEntity.getIdentity());
String wechatAppKey = apikeyRelationEntities.get(0).getWechatAppKey();
String wechatSecret = apikeyRelationEntities.get(0).getWechatSecret();
String token = WechatSendMsgUtil.getToken(wechatAppKey, wechatSecret, getTokenUrl);
wechatMiniProgramEntity.setToken(token);
stringRedisUtil.set(wechatMiniProgramEntity.getApikey(), token, 7000);
}
}
//发送小程序消息
String result = WechatSendMsgUtil.sendMiniProgramMsg(wechatMiniProgramEntity, sendMiniPUrl, data);
logger.info("小程序发送结果:" + result);
JSONObject jsonResult = JSONObject.parseObject(result);
String errCode = jsonResult.getString("errcode");
String errMsg = jsonResult.getString("errmsg");
try {
PushMessageEntity miniProgramMsg = miniProgramMsg(wechatMiniProgramEntity, data);
} catch (Exception ex) {
logger.error("解析IP地址失败!", ex);
ResultData.build("500", "服务解析错误");
}
return ResultData.build(errCode, errMsg,null);
}
/**
* @program: cjkj
* @description: 微信公众号发送消息工具类
* @author: Mr.Wang
* @create: 2020-03-31 00:40
**/
public class WechatSendMsgUtil {
/**
* 获取token
*
* @return token
*/
public static String getToken(String appid, String secret, String getTokenApi) {
//授予形式
String grant_type = "client_credential";
//接口地址拼接参数
getTokenApi = getTokenApi + "?grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret;
String tokenJsonStr = doGetPost(getTokenApi, "GET", null);
JSONObject tokenJson = JSONObject.parseObject(tokenJsonStr);
String token = tokenJson.get("access_token").toString();
System.out.println("获取到的TOKEN : " + token);
return token;
}
/***
* 发送公众号消息
* @param wechatOfficialEntity
*/
public static String SendWeChatMsg(WechatOfficialEntity wechatOfficialEntity, String sendMsgApi, String data, String miniprogram) {
//接口地址
sendMsgApi = sendMsgApi + "?access_token=" + wechatOfficialEntity.getToken();
//openId
String toUser = wechatOfficialEntity.getToUser();
//消息模板ID
String template_id = wechatOfficialEntity.getTemplateId();
String toUrl = wechatOfficialEntity.getToUrl();
//整体参数map
Map<String, Object> paramMap = new HashMap<String, Object>();
JSONObject dataJson = JSONObject.parseObject(data);
Map<String, Object> datamap = dataJson;
paramMap.put("touser", toUser);
paramMap.put("template_id", template_id);
paramMap.put("url", toUrl);
paramMap.put("miniprogram", miniprogram);
paramMap.put("data", datamap);
String result = doGetPost(sendMsgApi, "POST", paramMap);
return result;
}
/**
* 发送小程序消息
*/
public static String sendMiniProgramMsg(WechatMiniProgramEntity wechatMiniProgramEntity, String sendUrl, String data) {
//接口地址
sendUrl = sendUrl + "?access_token=" + wechatMiniProgramEntity.getToken();
//openId
String toUser = wechatMiniProgramEntity.getToUser();
//消息模板ID
String template_id = wechatMiniProgramEntity.getTemplateId();
String page = wechatMiniProgramEntity.getPage();
String miniprogramState = wechatMiniProgramEntity.getMiniProgramState();
String lang = wechatMiniProgramEntity.getLang();
//整体参数map
Map<String, Object> paramMap = new HashMap<String, Object>();
JSONObject dataJson = JSONObject.parseObject(data);
Map<String, Object> datamap = dataJson;
paramMap.put("touser", toUser);
paramMap.put("template_id", template_id);
paramMap.put("page", page);
paramMap.put("page", page);
paramMap.put("miniprogram_state", miniprogramState);
paramMap.put("lang", lang);
paramMap.put("data", datamap);
String result = doGetPost(sendUrl, "POST", paramMap);
return result;
}
/**
* 调用接口 post
*
* @param apiPath
*/
public static String doGetPost(String apiPath, String type, Map<String, Object> paramMap) {
OutputStreamWriter out = null;
InputStream is = null;
String result = null;
try {
URL url = new URL(apiPath);// 创建连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(true);
connection.setRequestMethod(type); // 设置请求方式
connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
connection.connect();
if (type.equals("POST")) {
out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8编码
out.append(JSON.toJSONString(paramMap));
out.flush();
out.close();
}
// 读取响应
is = connection.getInputStream();
int length = (int) connection.getContentLength();// 获取长度
if (length != -1) {
byte[] data = new byte[length];
byte[] temp = new byte[512];
int readLen = 0;
int destPos = 0;
while ((readLen = is.read(temp)) > 0) {
System.arraycopy(temp, 0, data, destPos, readLen);
destPos += readLen;
}
result = new String(data, "UTF-8"); // utf-8编码
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
}
/**
* @program: cjkj
* @description: 微信公众号实体类
* @author: Mr.Wang
* @create: 2020-03-30 16:11
**/
@Data
public class WechatOfficialEntity implements Serializable {
/**
* 服务注册标识
*/
private String apikey;
/**
* 账号唯一标识
*/
private String identity;
/**
* 微信返回的ACCESS_TOKEN
*/
private String token;
/**
* 发送到用户的openid
*/
private String toUser;
/**
* 消息模板id
*/
private String templateId;
/**
* 点击跳转的url
*/
private String toUrl;
}
/**
* @program: cjkj
* @description: 小程序实体类
* @author: Mr.zhang
* @create: 2020-04-02 15:45
**/
@Data
public class WechatMiniProgramEntity {
/**
* 系统唯一标识
*/
private String apikey;
/**
* 账号唯一标识
*/
private String identity;
private String token;
/**
* 接收者(用户)的 openid
*/
private String toUser;
/**
* 所需下发的模板消息的id
*/
private String templateId;
/**
* 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。
* 该字段不填则模板无跳转。
*/
private String page;
/**
* 表单提交场景下,为 submit 事件带上的 formId;支付场景下,为本次支付的 prepay_id
*/
private String formId;
/**
* 模板需要放大的关键词
* 不填则默认无放大
*/
private String emphasisKeyword;
/**
* 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
*/
private String lang;
/**
* 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
*/
private String miniProgramState;
}
公众号调用方式:
地址:/api-message/wechat/sendMessage
| 参数 | 含义 | 数据类型 | 是否必填 | 说明 |
| apikey | 注册分配的code | String | 是 | |
| identity | 账号唯一标识 | String | 是 |
|
| toUser | 发送用户的openid | String | 是 | |
| templateId | 模板编号 | String | 是 |
|
| url | 点击跳转地址 | String | 否 |
|
| miniProgram | 跳小程序所需数据,不需跳小程序可不用传该数据 | String | 否 | 格式:{"appid":"http://www.baidu.com","pagepath":"231"} |
| data | 模板数据 | String | 是 |
|
其中data的数据是json格式的字符串。案例如下:
{
"first":{
"value":"恭喜你购买成功!"
},
"keyword1":{
"value":"巧克力"
},
"keyword2":{
"value":"39.8元"
},
"keyword3":{
"value":"2014年9月22日"
},
"remark":{
"value":"欢迎再次购买!",
"color":"#173177"
}
}
小程序的调用方式:
地址:/api-message/wechat/sendMiniProgramMessage
| 参数 | 含义 | 数据类型 | 是否必填 | 说明 |
| apikey | 注册分配的code | String | 是 | |
| identity | 账号唯一标识 | String | 是 |
|
| toUser | 发送用户的openid | String | 是 | |
| templateId | 模板编号 | String | 是 |
|
| page | 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 | String | 否 |
|
| miniProgram | 跳小程序所需数据,不需跳小程序可不用传该数据 | String | 否 |
|
| data | 模板数据 | String | 是 | 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } |
| lang | 进入小程序查看”的语言类型 | string |
| 支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN |
postman、测试发送公众号



1万+

被折叠的 条评论
为什么被折叠?



