目前微信官网接口文档给的一些信息比较精简,当初做微信分享踩了不少坑。在项目完结后,对一些踩坑做一些总结。顺便分享自己一个完整的案例。希望能对以后涉足这一块的能有所帮助。
1、登入微信公众平台
(1)获取appid和appSecret
(2)设置JS接口安全域名(需要有一个合法、可以访问的域名)
2.引入JS文件
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
3、前端代码(由于我的前端使用Vue开发,为了能失识别微信接口函数,所以函数名开头加window)
let links= 分享出去的链接 ;
let title= 分享的标题 ;
let desc= 分享的详情介绍 ;
let imgUrl=分享的缩略图展示;
window.wx.config({
debug: false,
appId: 你的appid,
timestamp: 时间戳,
nonceStr: 随机字符串,
signature: 签名,
jsApiList: [
'onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'
]
})
window.wx.ready(function () {
window.wx.onMenuShareTimeline({
title: title, // 分享标题
desc: desc, // 分享描述
link:links, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
alert("分享到朋友圈成功")
},
cancel: function () {
alert("分享失败,您取消了分享!")
}
});
//微信分享菜单测试
window.wx.onMenuShareAppMessage({
title:title, // 分享标题
desc: desc, // 分享描述
link: links, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
alert("成功分享给朋友")
},
cancel: function () {
alert("分享失败,您取消了分享!")
}
});
window.wx.onMenuShareQQ({
title:title, // 分享标题
desc: desc, // 分享描述
link:links, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
alert("成功分享给QQ")
},
cancel: function () {
alert("分享失败,您取消了分享!")
}
});
window.wx.onMenuShareWeibo({
title:title, // 分享标题
desc: desc, // 分享描述
link: links, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
alert("成功分享给朋友")
},
cancel: function () {
alert("分享失败,您取消了分享!")
}
});
window.wx.onMenuShareQZone({
title:title, // 分享标题
desc: desc, // 分享描述
link: links, // 分享链接
imgUrl: imgUrl, // 分享图标
success: function () {
alert("成功分享给朋友")
},
cancel: function () {
alert("分享失败,您取消了分享!")
}
});
});
window.wx.error(function(res){
alert(res)
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
4、后台代码 (目前官网给出access_token每日请求次数上限为2000,每次请求值得有效时间为7200s,即2个小时。当7200有效时间并不一定可靠。我这里是每隔一个小时进行一次存储。)
/**
*
* 功能描述: 获取微信分享签名
*
* @param:
* @return:
*/
@RequestMapping(value = "getSign", method = RequestMethod.POST)
@ResponseBody
@RestAuth(isPublic = true)
public APIResult<WinXinEntity> getSign(HttpServletRequest request,HttpServletResponse response,@RequestBody Map<String,String> map) throws IOException {
APIResult<WinXinEntity> result = new APIResult<>();
String accessToken = null;
SysInfo sysInfo = null;
sysInfo = sysInfoService.selectInfo();
if(sysInfo==null){
String grant_type = "client_credential";// 获取access_token填写client_credential
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的&secret=你的";
//获取accessToken信息
String data = HttpUtils.loadJSON(url);
//string转Map
Map<String,String> accessTokenMap = strToMap(data);
accessToken = accessTokenMap.get("access_token");
System.out.print("项目地址accessToken:"+accessToken);
System.out.print("地址返回结果:"+data);
sysInfoService.saveInfo(accessToken);
}else {
accessToken = sysInfo.getAccessToken();
}
String ticketurl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";// 获取ticketurl
//获取ticket信息
String ticketData = HttpUtils.loadJSON(ticketurl);
//string转Map
Map<String,String> ticketMap = strToMap(ticketData);
String ticket = ticketMap.get("ticket");
String strUrl = map.get("url");
//获取参数
WinXinEntity wx = new WinXinEntity();
Map<String, String> ret = Sign.sign(ticket, strUrl);
wx.setTicket(ret.get("jsapi_ticket"));
wx.setSignature(ret.get("signature"));
wx.setNoncestr(ret.get("nonceStr"));
wx.setTimestamp(ret.get("timestamp"));
System.out.println("\n\n" + ret.toString() + "\n\n");
result.setResult(wx);
result.setCode(ResultPacketCode.APIResultCode.Success.getCode());
return result;
}
5、HttpUtils请求类
package com.gd.common.serviceImpl;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.X509TrustManager;
import org.apache.log4j.Logger;
/**
* @Description:
*/
public class HttpUtils {
public static String loadJSON (String url) {
StringBuilder json = new StringBuilder();
try {
URL oracle = new URL(url);
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine = null;
while ( (inputLine = in.readLine()) != null) {
json.append(inputLine);
}
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
return json.toString();
}
}
6、签名类
package com.gd.common.config;
import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
public class Sign {
public static Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
System.out.println(string1);
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
// 生成签名
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
// 生成nonceStr
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
// 生成timestamp
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}
如仍有疑问,可以私信我。或在下方留言