微信公众号开发——java后台开发(二)
之前已经将开发的准备工作做完,下面我们介绍具体的业务开发。
由于微信订阅号的部分功能缺失,而个人不能进行服务号的申请,我这里使用微信测试账号进行业务功能的测试。
公众平台测试账号
在订阅号开发者工具栏选择“公众平台测试账号”进入测试账号页面
上图中在接口配置里填写我们映射的域名信息,以http://或https:// 开头,Token填写我们SignUtil.java中所写的TOKEN,点击提交按钮,配置成功则证明我们的配置有效,可以进行接下来的开发。
微信公众号要在:设置->安全中心->IP白名单设置中设置IP白名单,才能获取access_token。
获取access_token
access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
获取access_token相关信息可参考微信开发文档中“开始开发->获取access_token”部分。
接口调用请求说明
https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
grant_type | 是 | 获取access_token填写client_credential |
appid | 是 | 第三方用户唯一凭证 |
secret | 是 | 第三方用户唯一凭证密钥,即appsecret |
返回说明
正常情况下,微信会返回下述JSON数据包给公众号:
{“access_token”:“ACCESS_TOKEN”,“expires_in”:7200}
错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):
{“errcode”:40013,“errmsg”:“invalid appid”}
获取access_token
由于access_token的时效性和每天获取次数的限制,我们将定时获取access_token并将获取到的token存储到数据库中,使用的时候从数据库中获取,当然也可以存储到缓存中如redis。
使用定时任务调用接口执行access_token的刷新。
@Service
public class AccessTokenServiceImpl implements AccessTokenService {
private static final Logger LOGGER = LoggerFactory.getLogger(AccessTokenServiceImpl.class);
@Autowired
private RestTemplate restTemplate;
@Autowired
private WechatParamMapper wechatParamMapper;
@Override
public String getAccessToken() {
WechatParamDO wechatParamDO = wechatParamMapper.selectByParamCode(Constants.WeChat.ACCESS_TOKEN);
if (wechatParamDO != null && !StringUtil.isBlank(wechatParamDO.getParamValue())) {
return wechatParamDO.getParamValue();
} else {
LOGGER.error("获取AccessToken失败,weChatParamDO = {}", wechatParamDO);
throw new AncbException(ResultEnum.FAIL.getCode(), "获取AccessToken失败");
}
}
@Override
public int setAccessToken() throws Exception {
String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
requestUrl = requestUrl.replace("APPID", Constants.WeChat.APP_ID);
requestUrl = requestUrl.replace("APPSECRET", Constants.WeChat.APP_SECRET);
LOGGER.error("请求AccessToken,requestUrl=={}", requestUrl);
AccessTokenResp accessTokenResp = restTemplate.getForObject(requestUrl, AccessTokenResp.class);
String accessToken = accessTokenResp.getAccessToken();
return wechatParamMapper.updateByParamCode(Constants.WeChat.ACCESS_TOKEN, accessToken);
}
}
public class AccessTokenResp {
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("expires_in")
private Integer expiresIn;
/**
* 获取 @JsonProperty("access_token")
*
* @return accessToken @JsonProperty("access_token")
*/
public String getAccessToken() {
return this.accessToken;
}
/**
* 设置 @JsonProperty("access_token")
*
* @param accessToken @JsonProperty("access_token")
*/
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
/**
* 获取 @JsonProperty("expires_in")
*
* @return expiresIn @JsonProperty("expires_in")
*/
public Integer getExpiresIn() {
return this.expiresIn;
}
/**
* 设置 @JsonProperty("expires_in")
*
* @param expiresIn @JsonProperty("expires_in")
*/
public void setExpiresIn(Integer expiresIn) {
this.expiresIn = expiresIn;
}
}
模板消息接口
1. 模板创建
公众号模板消息,向认证后的服务号开放。所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限。
模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。
申请步骤:
第一步,在功能->添加功能插件处申请模板消息使用权限。
第二步,选择公众账号服务所处的两个行业,每月可更改一次所选行业。
第三步,在所选择行业的模板库中选用已有的模板进行调用(调用详见接口文档)。
第四步,管理该账号自己选用的模板(每个账号可以同时使用10个模板)。
可参考相关百度文章。
在我们测试中,可以在测试账号页面下方直接新增测试模板。
模板内容中“{{}}”中为固定模式,如{{first.DATA}} ,添加测试模板的过程中不要去进行修改,添加完成后如下图所示,图中模板ID用于我们后台调接口所用。
2. 发送模板消息
模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。
发送模板消息,首先我们先看一下发送模板消息的样例,json数据格式如下所示。
{
"touser":"OPENID",
“url”:“URL”,
"template_id":"QI4JojaGvL9-5ynjwFwOSPqH2eWXHpr7ZeseysefKqc",
"data":{
"first": {
"value":"恭喜你购买成功!",
"color":"#173177"
},
"product":{
"value":"巧克力",
"color":"#173177"
},
"amount": {
"value":"39.8元",
"color":"#173177"
},
"time": {
"value":"2014年9月22日",
"color":"#173177"
},
"remark":{
"value":"欢迎再次购买!",
"color":"#173177"
}
}
}
对此我们将创建两个类来存储这些数据。
public class WechatTemplate {
/**
* 微信用户openID
*/
@JsonProperty("touser")
private String toUser;
/**
* 模板id
*/
@JsonProperty("template_id")
private String templateId;
/**
* 路径url
*/
private String url;
/**
* 请求参数
*/
private Map<String, TemplateData> data;
public WechatTemplate() {
}
public String getToUser() {
return this.toUser;
}
public void setToUser(String toUser) {
this.toUser = toUser;
}
public String getTemplateId() {
return this.templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, TemplateData> getData() {
return this.data;
}
public void setData(Map<String, TemplateData> data) {
this.data = data;
}
}
public class TemplateData {
/**
* 值
*/
private String value;
/**
* 颜色
*/
private String color;
public TemplateData(String value, String color) {
this.value = value;
this.color = color;
}
public String getValue() {
return this.value;
}
public String getColor() {
return this.color;
}
public void setColor(String color) {
this.color = color;
}
}
接下来我们发送上面的数据到微信服务器,接口调用请求说明
http请求方式: POST
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
@Service
public class TemplateMessageServiceImpl implements TemplateMessageService {
private static final Logger LOGGER = LoggerFactory.getLogger(TemplateMessageServiceImpl.class);
@Autowired
private RestTemplate restTemplate;
@Override
public WechatResponse sendTemplateMessage(String accessToken, WechatTemplate wechatTemplate) {
WechatResponse wechatResponse;
String url = new StringBuffer("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=")
.append(accessToken).toString();
wechatResponse = restTemplate.postForObject(url, wechatTemplate, WechatResponse.class,new HashMap<String,String>());
return wechatResponse;
}
}
返回码说明
在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:
{
“errcode”:0,
“errmsg”:“ok”,
“msgid”:200228332
}
使用效果
上述已将模板推送进行一个简单的说明,如要更深入了解,可以查看微信开发文档。