接触微信公众平台的开发,做好记录。
关于申请公众号、订阅号服务号企业号之间的区别等等就不多废话了。
一、启动开发者模式,配置自己的服务器
1. 获取公众号信息:
进入微信公众平台后台——》基本配置,获取自己的AppID(开发者ID)和AppSecret(开发者密码),这相当于开发模式的账号密码,需要注意的是获取到的AppSecret需要自己保存起来,否则忘记了是无法在后台查看需要重新获取的。
2. 配置服务器信息:
在基本配置处,启用服务器配置,也就是启用开发者模式,编辑模式的所有设置将失效。
在URL处设置自己的服务器微信项目地址;Token为自己随意设置的令牌标记;EncodingAESKey是选择加密模式时需要使用的密钥。
二、接入验证,将公众号与服务器相连接
1. 需要特别注意的是,在服务器URL配置无误的情况下,还需要将服务器IP添加到IP白名单中。
2. 验证过程开发文档写的很清楚:
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:
- signature:微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
- timestamp:时间戳
- nonce:随机数
- echostr:随机字符串
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
3.实现如下:
通过request获取参数:
```
logger.info("=======================开始接入验证==========================");
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
PrintWriter writer = response.getWriter();
if (CheckUtil.checkSignature(signature, timestamp, nonce)) {
writer.print(echostr);
logger.info("==============验证成功,服务器地址与公众号匹配成功===============");
}
```
对参数进行处理:
```
String[] arr = new String[] {token,timestamp,nonce};
//排序
Arrays.sort(arr);
//生成字符串
StringBuffer content = new StringBuffer();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
//sha1加密
String temp = getSha1(content.toString());
return temp.equals(signature);
```
sha1加密方法:
/**
* Sha1加密方法
* @param str
* @return
*/
public static String getSha1(String str) {
if (str == null || str.length() == 0) {
return null;
}
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
三、获取access_token
关于如何获取access_token,其实开发文档中有很详细的介绍,其实如何保存access_token比如何获取access_token更重要,关于如何保存access_token,下一篇再介绍。
1. 获取access_token:
access_token是公众号的全局唯一接强调内容口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
公众平台的API调用所需的access_token的使用及生成方式说明:
1)、建议公众号开发者使用中控服务器统一获取和刷新Access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;
2)、目前Access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,新老access_token都可用,这保证了第三方业务的平滑过渡;
3)、Access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知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}
- access_token:获取到的凭证
- expires_in:凭证有效时间,单位:秒
2.实现:
调用doGet()方法,调用微信提供的接口:
/**
* 调用api获取access_token
*/
public class GetAccess_Token extends BaseApiUtil {
private static final String ACCESS_TOKEN_API = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
public static Access_Token getAccess_Token() {
String url = ACCESS_TOKEN_API.replace("APPID", AppID).replace("APPSECRET", AppSecret);
JSONObject jsonObject = WeChatUtil.doGet(url);
Access_Token access_Token = new Access_Token();
if (jsonObject!=null) {
access_Token.setAccess_token(jsonObject.getString("access_token"));
access_Token.setExpress_in(jsonObject.getInt("expires_in"));
}
return access_Token;
}
doGet()方法的封装:
/**
* 对doget方法的封装,以便通过get请求的接口的调用
* @param url
* @return
*/
public static JSONObject doGet(String url) {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
JSONObject jsonObject = null;
try {
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity!=null) {
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSONObject.fromObject(result);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}