项目调用微信JS-SDK接口主要是为了可以分享自定义的页面。直接说在看文档开发过程中的坑,文档中有的就简略了。
1. 获得JsapiTicket直接携带token访问接口即可。
2. 时间戳的获取,在微信的sha1加密测试页面,时间戳的长度为10个数字,但是超过10个数字时,代码也不报错,为了避免踩坑,的我的时间戳是这样的
String timestamp = new SimpleDateFormat("MMddHHmmss").format(new Date());
3. sha1加密,加密前的参数按照官网文档要求,需要按照自然顺序排序,但是是因为参数名是固定的,所以排序后的顺序也不会变,我就直接按照自然顺序拼接成了字符串:
String str= "jsapi_ticket="+ticke+"&noncestr="+nonce+"×tamp="+timestamp+"&url="+url;
在转化为16进制的字符串时,字母部分用小写,加密代码:
public static String checkSignature(String ticke, String timestamp, String nonce,String url) {
String str= "jsapi_ticket="+ticke+"&noncestr="+nonce+"×tamp="+timestamp+"&url="+url;
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA1");
byte[] digest = md.digest(str.getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return tmpStr;
}
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
4. 准备好参数,开始写js,需要分享功能页面必须是公众号功能设置的域名下的页面:
4.1 在需要分享功能的页面引入js
4.2 页面加载的时候加载,js分享所需要的配置::
function weixin(){
var targetUrl = encodeURIComponent(location.href.split("#")[0]);
$.ajax({
type:"post",
async:false,
data: {"targetUrl":targetUrl},
dataType:"json",
url: webPath+"/newToken_getJsapiTicket.action",
success : function(data){
// alert(data.appid + "--" + data.times + "--" + data.nonce+ "--" + data.sign )
wx.config({ // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: data.appid, // 必填,公众号的唯一标识
timestamp:data.times , // 必填,生成签名的时间戳
nonceStr: data.nonce, // 必填,生成签名的随机串
signature: data.sign,// 必填,签名
jsApiList: ['onMenuShareAppMessage']
});
}
});}
坑坑坑:动态获得当前页面的url:
一定要加上encode,同时,在请求的后台通过URLDecode解密,不然后台加密的url和wx.config加密的很可能不一样,从而报invalid signature
后台代码:
public void getJsapiTicket(){
String Url = request.getParameter("targetUrl");
Map resultMap = new HashMap();
try {
String token = CommonUtils.getJsapiTicket();
String timestamp = new SimpleDateFormat("MMddHHmmss").format(new Date());;
String none = "weixin";
String shaStr = SignUtil.checkSignature(token,timestamp,none,URLDecode(Url));
resultMap.put("times",timestamp);
resultMap.put("nonce",none);
resultMap.put("sign",shaStr);
resultMap.put("appid","wxb18664ff1d0f9e6b");
} catch (Exception e) {
e.printStackTrace();
}
writerPrint(JSONObject.fromObject(resultMap).toString());
}
4.3 你用什么分享接口,加载wx.config里标明,我只测试了分享给朋友的接口
function baidu(){
wx.onMenuShareAppMessage({
title: 'https://www.baidu.com/', // 分享标题
desc: 'wwwwwww', // 分享描述
link: '域名/项目名/token_tiaozhuan.action?url=https://www.baidu.com/', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
success: function (data) {
location.href = data.url;
}
});
}
这个方法就是复写了微信分享时的分享内容,并不能直接调用好友列表,分享,真正的分享还需要手动点击右上方的三个点,选择分享给好友
然后点击分享内容的时候,微信会想link参数的路径发送请求,你直接在代码里跳转就ok了
public void tiaozhuan(){
try {
String Url = request.getParameter("url");
response.sendRedirect(Url);
} catch (Exception e) {
e.printStackTrace();
}
}