记一次微信公众号分享sdk
这里我的脚本是用jquery写的,不带框架源码
首先创建jsp引入JavaScript微信分享js
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
引入jquery
<script type="text/javascript" src="../script/jquery.js"></script>
这里是使用的是http请求,以下贡献http请求工具类
package com.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
/**
* http get post
* @author 为中华之崛起而编程
*
*/
@SuppressWarnings("all")
public class HttpUtil {
/**
* 执行HTTP GET请求,返回请求响应的内容
* @param url
* 请求的URL地址
* @return
* 返回请求响应的内内容
* @throws IOException
* @throws ClientProtocolException
*/
public static String doGet(String url) throws IOException {
StringBuffer sb = new StringBuffer();
HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().getParams()
.setConnectionTimeout(2000);
GetMethod getMethod = new GetMethod(url);
try {
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,
2000);
httpClient.executeMethod(getMethod);
if (getMethod.getStatusCode() == HttpStatus.SC_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(
getMethod.getResponseBodyAsStream()));
String ln;
while ((ln = in.readLine()) != null) {
sb.append(ln);
}
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
getMethod.releaseConnection();
}
return null;
}
/**
* 执行HTTP POST请求,返回请求响应的内容
*
* @param url
* 请求的URL地址
* @param params
* 请求的查询的参数可以为null
* @return 返回请求响应的内容
* @throws IOException
*/
public static String doPost(String url, Map<String, String> map)
throws IOException {
StringBuffer sb = new StringBuffer();
HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().getParams()
.setConnectionTimeout(2000);
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
int i = 0;
NameValuePair[] data = new NameValuePair[map.size()];
for (Map.Entry<String, String> entry : map.entrySet()) {
data[i++] = new NameValuePair(entry.getKey(), entry.getValue());
}
postMethod.setRequestBody(data);
try {
postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,
2000);
postMethod.getParams().setParameter(
HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
httpClient.executeMethod(postMethod);
if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(
postMethod.getResponseBodyAsStream(), "UTF-8"));
String ln;
while ((ln = in.readLine()) != null) {
sb.append(ln);
}
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
postMethod.releaseConnection();
}
return null;
}
/**
* 执行HTTP POST请求,返回请求响应的内容
*
* @param url
* 请求的URL地址
* @param params
* 请求的查询参数可以为null
* @return 返回请求响应的内容
* @throws IOException
*/
public static String doPost(String url, String body) throws IOException {
StringBuffer sb = new StringBuffer();
HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().getParams()
.setConnectionTimeout(2000);
PostMethod postMethod = new PostMethod(url);
postMethod.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
postMethod.setRequestBody(body);
try {
postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,
2000);
postMethod.getParams().setParameter(
HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
httpClient.executeMethod(postMethod);
if (postMethod.getStatusCode() == HttpStatus.SC_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(
postMethod.getResponseBodyAsStream(), "UTF-8"));
String ln;
while ((ln = in.readLine()) != null) {
sb.append(ln);
}
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
postMethod.releaseConnection();
}
return null;
}
}
创建一个servlet,在servlet初始化时获取access_token
1.获取access_token地址:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=
2.获取ticket地址:https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=&type=jsapi
创建servlet初始化
public class InitServlet extends HttpServlet{
//这里创建一个线程2小时调用一次循环调用,预防access_token过期
private static ScheduledExecutorService POOL = Executors.newScheduledThreadPool(1);
//创建一个map存ticket
public static Map<String,String> map = new HashMap<String,String>();
public void init() throws ServletException {
POOL.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=&secret=d51ff270c9d161fd6065a0c5891ca802";
String json = HttpUtil.doGet(url);
Map mapss = JSON.parseObject(json, Map.class);
String access_token = (String)mapss.get("access_token");
url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
json = HttpUtil.doGet(url);
Map mapOne = JSON.parseObject(json, Map.class);
System.out.println(JSON.toJSONString(mapOne));
String jsapi_ticket = (String)mapOne.get("ticket");
map.put("ticket", jsapi_ticket);
} catch (IOException e) {
e.printStackTrace();
}
}
}, 0, 2 * 60 * 59 * 1000, TimeUnit.MILLISECONDS);
}
}
web.xml调用servlet初始化
<servlet>
<servlet-name>InitServlet</servlet-name>
<servlet-class>com.servlet.InitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
下面创建jsp获取全域名,第一次就是在全域名这里栽跟头,因为没有动态获取所以sdk验签一直失败,一定要确保url参数跟你访问的页面的url保持一致
<%
//访问页的url
String strBackUrl = "http://" + request.getServerName() + ":"+ request.getServerPort() + request.getContextPath() + request.getServletPath();
//参数
if(request.getQueryString() != null){
strBackUrl = strBackUrl + "?" + (request.getQueryString());
}
//获取项目启动时初始化好的ticket
String ticket = InitServlet.map.get("ticket");
//调用签名算法,存入返回参数
Map<String,String> map = Sha1.sign(ticket, strBackUrl);
%>
加入微信签名算法Sha1
package com.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
public class Sha1 {
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;
}
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
public static String getRandomString(int length){
//产生随机数
Random random=new Random();
StringBuffer sb=new StringBuffer();
//循环length次
for(int i=0; i<length; i++){
//产生0-2个随机数,既与a-z,A-Z,0-9三种可能
int number=random.nextInt(3);
long result=0;
switch(number){
//如果number产生的是数字0;
case 0:
//产生A-Z的ASCII码
result=Math.round(Math.random()*25+65);
//将ASCII码转换成字符
sb.append(String.valueOf((char)result));
break;
case 1:
//产生a-z的ASCII码
result=Math.round(Math.random()*25+97);
sb.append(String.valueOf((char)result));
break;
case 2:
//产生0-9的数字
sb.append(String.valueOf
(new Random().nextInt(10)));
break;
}
}
return sb.toString();
}
}
执行脚本
<script type="text/javascript">
$(function() {
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,企业号的唯一标识,此处填写企业号corpid
timestamp: '<%=map.get("timestamp")%>', // 必填,生成签名的时间戳
nonceStr: '<%=map.get("nonceStr")%>', // 必填,生成签名的随机串
signature: '<%=map.get("signature")%>',// 必填,签名,见附录1
jsApiList: [
'onMenuShareAppMessage',
'scanQRCode'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function () { //需在用户可能点击分享按钮前就先调用
var url = '自定义跳转url';
wx.onMenuShareAppMessage({
title: '', // 分享标题
desc: '', // 分享描述
link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
success: function () {
// 用户点击了分享后执行的回调函数
}
});
});
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
});
</script>
打开调试模式,返回config:ok就算是成功了,这里拿分享举例
还有一个就是,想多个页面都使用同一个自定义分享,把分享的sdk单独出来,要使用的页面去引用此页面就可以了