微信JS-SDK说明文档 :https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
获取借口参数工具类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
public class WeixinUtils {
private static final String openIdUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID1&secret=SECRET1&code=CODE1&grant_type=authorization_code";
private static final String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID1&secret=SECRET1";
private static final String ticketUrl = "http://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=ACCESS_TOKEN1";
public static final String appId = "";
public static final String appSecret = "";
public static final int baseLife = 3;
public static final String EndTime = "2015-11-31 00:00:01";
private static String accessToken=null;
private static String jsapiTicket=null;
public static String getOpenId(HttpServletRequest request) throws Exception {
String openId = null;
String code = request.getParameter("code");
if (StringUtils.isNotEmpty(code)) {
String url = openIdUrl.replace("APPID1", appId)
.replace("SECRET1", appSecret).replace("CODE1", code);
String result = getURLContent(url);
System.out.println(result);
openId = result.split("openid")[1].split("scope")[0]
.replaceAll("\"", "").replaceAll(",", "")
.replaceAll(" ", "").replaceAll(":", "");
System.out.println("openId" + openId);
}
return openId;
}
public static Map<String, String> setShareConfig(
HttpServletRequest request, String url) throws Exception {
ServletContext context = request.getSession().getServletContext();
//accessToken = (String) context.getAttribute("accessToken");
if (StringUtils.isEmpty(accessToken)) {
accessToken = getAccessToken();
context.setAttribute("accessToken", accessToken);
/*System.out.println(DateUtils.format(new Date(),
DateUtils.DATETIME_FORMAT)
+ "-------accessToken 超时,重新获取--------" + accessToken); */
}
//jsapiTicket = (String) context.getAttribute("jsapiTicket");
if (StringUtils.isEmpty(jsapiTicket)) {
jsapiTicket = getTicket(accessToken);
context.setAttribute("jsapiTicket", jsapiTicket);
/* System.out.println(DateUtils.format(new Date(),
DateUtils.DATETIME_FORMAT)
+ "-------jsapiTicket 超时,重新获取--------" + jsapiTicket); */
}
Map<String, String> ret = sign(jsapiTicket, url);
request.setAttribute("url", ret.get("url"));
request.setAttribute("jsapi_ticket", ret.get("jsapi_ticket"));
request.setAttribute("nonceStr", ret.get("nonceStr"));
request.setAttribute("timestamp", ret.get("timestamp"));
request.setAttribute("signature", ret.get("signature"));
request.setAttribute("appId", appId);
return ret;
};
private static String getTicket(String accessToken) throws Exception {
String ticket = null;
String url = ticketUrl.replace("ACCESS_TOKEN1", accessToken);
String result = getURLContent(url);
System.out.println(result);
ticket = result.split("ticket")[1].split("expires_in")[0]
.replaceAll("\"", "").replaceAll(",", "").replaceAll(" ", "")
.replaceAll(":", "");
System.out.println("ticket:" + ticket);
return ticket;
}
private static String getAccessToken() throws Exception {
String accessToken = null;
String url = accessTokenUrl.replace("APPID1", appId).replace("SECRET1",
appSecret);
String result = getURLContent(url);
System.out.println(result);
accessToken = result.split("access_token")[1].split("expires_in")[0]
.replaceAll("\"", "").replaceAll(",", "").replaceAll(" ", "")
.replaceAll(":", "");
System.out.println("accessToken:" + accessToken);
return accessToken;
}
private static String getURLContent(String url)
throws MalformedURLException, IOException {
String result = "";
BufferedReader in = null;
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
// 使用finally块来关闭输入流
if (in != null) {
in.close();
}
return result;
}
private static Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = UUID.randomUUID().toString().replaceAll("-", "")
.substring(0, 16).toLowerCase();
String timestamp = Long.toString(System.currentTimeMillis() / 1000);
String string1;
String signature = "";
// 注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
+ "×tamp=" + timestamp + "&url=" + url;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
System.out.println("key--" + string1);
System.out.println("url--" + url);
System.out.println("jsapi_ticket--" + jsapi_ticket);
System.out.println("nonceStr--" + nonce_str);
System.out.println("timestamp--" + timestamp);
System.out.println("signature--" + signature);
} catch (Exception 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;
}
/**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
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;
}
private void resetAccessTokenTicket(){//每两小时重置一次accessToken和jsapiTicket
accessToken=null;
jsapiTicket=null;
System.out.println("重置accessToken和jsapiTicket");
}
}
控制器方法
//微信jssdk
@RequestMapping(value="/getJssdk")
public void getJssdk(HttpServletRequest request,HttpServletResponse response,Model model,
@RequestParam(defaultValue = "", required = false, value = "url") String url){
try {
String ua = ((HttpServletRequest) request).getHeader("user-agent")
.toLowerCase();
if (ua.indexOf("micromessenger") > 0) {
Map<String,String> map= WeixinUtils.setShareConfig(request, url);
WebUtils.flushObject(map, response);
}
} catch (Exception e) {
e.printStackTrace();
WebUtils.flushFailureByMsg(response, "系统出错请与工作人员联系!");
}
}
页面js
$.ajax({
type : "post",
dataType : "json",
url : "",
data : {
url : location.href.split('#')[0]
},
complete : function() {
},
success : function(msg) {
console.log(msg.jsapi_ticket);
wx.config({
debug : false, // 调试
appId : '', // 必填,公众号的唯一标识
timestamp : msg.timestamp, // 必填,生成签名的时间戳
nonceStr : msg.nonceStr, // 必填,生成签名的随机串
signature : msg.signature,// 必填,签名,见附录1
jsApiList : [ 'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'showOptionMenu',
'onMenuShareQZone', ]
// 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
},
});
var shareTitle = "法国游已经近在咫尺了,是朋友就帮我一把吧!";
var shareDesc = "法国游已经近在咫尺了,是朋友就帮我一把吧!";
var shareImg = "http://c.csdnimg.cn/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png";
var url = window.location.href;
wx.ready(function() {
sharedata = {
title: shareTitle, // 分享标题
desc: shareDesc , // 分享描述
link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
mgUrl:shareImg,// 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function(){
//alert('分享成功');
},
cancel: function(){
//alert('您取消了分享');
}
};
wx.onMenuShareAppMessage(sharedata);
wx.onMenuShareTimeline(sharedata);
wx.onMenuShareQZone(sharedata);
wx.onMenuShareWeibo(sharedata);
});