第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容
第一部分:微信JS-SDK介绍
微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
本次的内容:
实现:分享到朋友圈,qq,qq空间,微信朋友的功能。
基础接口
判断当前客户端版本是否支持指定JS接口
wx.checkJsApi({
jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
}
});
备注:checkJsApi接口是客户端6.0.2新引入的一个预留接口,第一期开放的接口均可不使用checkJsApi来检测。
获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
wx.onMenuShareTimeline({
title: '', // 分享标题
link: '', // 分享链接
imgUrl: '', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.onMenuShareAppMessage({
title: '', // 分享标题
desc: '', // 分享描述
link: '', // 分享链接
imgUrl: '', // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
获取“分享到QQ”按钮点击状态及自定义分享内容接口
wx.onMenuShareQQ({
title: '', // 分享标题
desc: '', // 分享描述
link: '', // 分享链接
imgUrl: '', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
wx.onMenuShareWeibo({
title: '', // 分享标题
desc: '', // 分享描述
link: '', // 分享链接
imgUrl: '', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
获取“分享到QQ空间”按钮点击状态及自定义分享内容接口
wx.onMenuShareQZone({
title: '', // 分享标题
desc: '', // 分享描述
link: '', // 分享链接
imgUrl: '', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
附录2-所有JS接口列表
版本1.0.0接口
- onMenuShareTimeline
- onMenuShareAppMessage
- onMenuShareQQ
- onMenuShareWeibo
- onMenuShareQZone
附录3-所有菜单项列表
- 发送给朋友: "menuItem:share:appMessage"
- 分享到朋友圈: "menuItem:share:timeline"
- 分享到QQ: "menuItem:share:qq"
- 分享到Weibo: "menuItem:share:weiboApp"
- 收藏: "menuItem:favorite"
- 分享到FB: "menuItem:share:facebook"
- 分享到 QQ 空间/menuItem:share:QZone
详细的可以参照微信官方的介绍: 微信JS-SDK说明文档
第二部分:分享方法的实现。
那么,我们如何来实现这个分享内容呢?
JSSDK使用步骤
步骤一:绑定域名
1. 先登录微信公众平台 ,登录后可在“开发者中心”查看对应的接口权限。
说明了有这个分享的权限。
2. 进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
js域名,一般不用http这样的开头。
步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
请注意,如果你的页面启用了https,务必引入 https://res.wx.qq.com/open/js/jweixin-1.0.0.js ,否则将无法在iOS9.0以上系统中成功使用JSSDK
如需使用摇一摇周边功能,请引入 jweixin-1.1.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,见附录1
jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
注意,我这里只是动态获取,并没有做缓存,如果有需要的同学,需要做一些缓存。
如何获取以上的参数呢?
package com.souvc.weixin.util; import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest; import net.sf.json.JSONObject; public class WeixinUtil { /**
* 方法名:httpRequest</br>
* 详述:发送http请求</br>
* 开发人员:souvc </br>
* 创建时间:2016-1-5 </br>
* @param requestUrl
* @param requestMethod
* @param outputStr
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonObject;
} /**
* 方法名:getWxConfig</br>
* 详述:获取微信的配置信息 </br>
* 开发人员:souvc </br>
* 创建时间:2016-1-5 </br>
* @param request
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
public static Map<String, Object> getWxConfig(HttpServletRequest request) {
Map<String, Object> ret = new HashMap<String, Object>(); String appId = "xxxx"; // 必填,公众号的唯一标识
String secret = "xxxx"; String requestUrl = request.getRequestURL().toString();
String access_token = "";
String jsapi_ticket = "";
String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" + secret; JSONObject json = WeixinUtil.httpRequest(url, "GET", null); if (json != null) {
//要注意,access_token需要缓存
access_token = json.getString("access_token"); url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi";
json = WeixinUtil.httpRequest(url, "GET", null);
if (json != null) {
jsapi_ticket = json.getString("ticket");
}
}
String signature = "";
// 注意这里参数名必须全部小写,且必须有序
String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "×tamp=" + timestamp + "&url=" + requestUrl;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(sign.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("appId", appId);
ret.put("timestamp", timestamp);
ret.put("nonceStr", nonceStr);
ret.put("signature", signature);
return ret;
} /**
* 方法名:byteToHex</br>
* 详述:字符串加密辅助方法 </br>
* 开发人员:souvc </br>
* 创建时间:2016-1-5 </br>
* @param hash
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
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; }
}
注意:以上需要替换成自己的appid和secret 。
步骤四:通过ready接口处理成功验证
wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
根据以上的步骤,我们写了一个页面:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@page language="java" import="com.souvc.weixin.util.WeixinUtil" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>欢迎访问搜投网 www.souvc.com </title>
<%
Map<String,Object> ret = new HashMap<String,Object> ();
ret=WeixinUtil.getWxConfig(request);
request.setAttribute("appId", ret.get("appId"));
request.setAttribute("timestamp", ret.get("timestamp"));
request.setAttribute("nonceStr", ret.get("nonceStr"));
request.setAttribute("signature", ret.get("signature"));
%>
</head>
<body> 欢迎访问搜投网! </body> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript"> // 微信信息的以及调用的配置
wx.config({
debug: false,
appId: '${appId}',
timestamp: '${timestamp}',
nonceStr: '${nonceStr}',
signature: '${signature}',
jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone']
}); wx.ready(function(){
// 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
wx.onMenuShareTimeline({
title: '第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息', // 分享标题
link:"http://www.cnblogs.com/liuhongfeng/p/5099149.html",
imgUrl: "http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_1442809977405.jpg" // 分享图标
});
// 获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.onMenuShareAppMessage({
title: '第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息', // 分享标题
desc: "第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息", // 分享描述
link:"http://www.cnblogs.com/liuhongfeng/p/5057167.html",
imgUrl: "http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_QQ%E5%9B%BE%E7%89%8720151118180508.png", // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
}); //获取“分享到QQ”按钮点击状态及自定义分享内容接口
wx.onMenuShareQQ({
title: '第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单', // 分享标题
desc: '第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单', // 分享描述
link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享链接
imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
}); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口
wx.onMenuShareWeibo({
title: '分享到腾讯微博标题', // 分享标题
desc: '分享到腾讯微博描述', // 分享描述
link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享链接
imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
}); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口
wx.onMenuShareQZone({
title: '分享到QQ空间标题', // 分享标题
desc: '分享到QQ空间描述', // 分享描述
link: 'http://www.cnblogs.com/liuhongfeng/p/4857312.html', // 分享链接
imgUrl: 'http://images.cnblogs.com/cnblogs_com/liuhongfeng/737147/o_qrcode_for_gh_228cd30523bc_258.jpg', // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
}); });
</script> </html>
步骤五: 部署到服务器。然后访问到这个页面,用微信扫一扫。然后分享到我们设定的接口。
效果如下:
发给微信朋友的效果:
分享到朋友圈的效果:
分享到qq空间的效果:
分享给朋友的效果:
恭喜你,配置成功!!
其他文章关联:
第一篇:微信公众平台开发实战Java版之了解微信公众平台基础知识以及资料准备
第二篇 :微信公众平台开发实战Java版之开启开发者模式,接入微信公众平台开发
第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装
第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理
第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token
第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单
第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息
第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息
第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容
第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容的更多相关文章
- 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息
第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...
- 第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息
在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据O ...
- 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单
我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...
- 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token
一.access_token简介 为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等, 开 ...
- 第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理
温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众 ...
- 第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装
微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者 ...
- 第二篇 :微信公众平台开发实战Java版之开启开发者模式,接入微信公众平台开发
第一部分:微信公众号对接的基本介绍 一.填写服务器配置信息的介绍 登录微信公众平台官网后,进入到公众平台后台管理页面. 选择 公众号基本设置->基本配置 ,点击“修改配置”按钮,填写服务器地址( ...
- 第一篇:微信公众平台开发实战Java版之了解微信公众平台基础知识以及资料准备
相信很多人或多或少听说了微信公众平台的火热.但是开发还是有一点门槛,鉴于挺多朋友问我怎么开发,问多了,自己平时也进行以下总结.所以下面给大家分享一下我的经验: 微信公众号是什么? 官网的介绍:再小的个 ...
- 微信公众平台开发实战Java版之如何网页授权获取用户基本信息
第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...
随机推荐
- java switch语句注意的事项
1.switch语句使用的变量只能是byte.char.short.string数据类型. 2.case后面gender数据必须是一个常量. 3.switch的停止条件: switch语句一旦比配上了 ...
- Dir /U /c 输出Unicode字符的特性
比如某个目录列表如下: D:\Spec\a.txtD:\Spec\Dir・C.txtD:\Spec\else.txtD:\Spec\קתקווה.dataD:\Spec\中・文.txt 直接dir / ...
- Linq专题之创建Linq查询表达式
本节我们主要介绍一下如何创建查询集合类型,关系数据库类型,DataSet对象类型和XML类型的数据源的Linq查询表达式. 下面在实例代码ReadyCollectionData()函数创建了准备的数据 ...
- .Net 配置文件--继承ConfigurationSection实现自定义处理类处理自定义配置节点
除了使用继承IConfigurationSectionHandler的方法定义处理自定义节点的类,还可以通过继承ConfigurationSection类实现同样效果. 首先说下.Net配置文件中一个 ...
- css3文字导航鼠标悬停气泡动画特效源码下载
效果体验:http://hovertree.com/texiao/css3/8/ 效果图: 点击这里下载:http://hovertree.com/h/bjaf/8d5vmddq.htm 更多特效:h ...
- Retention、Documented、Inherited三种注解
Retention注解 Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值:1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源 ...
- Json Utils
import java.util.List;import java.util.Map; import net.sf.json.JSONArray;import net.sf.json.JSONObje ...
- Incorrect string value: '\xF0\x90\x8D\x83...' for column 通用解决方案
mysql插入非ascii字符时报这个错的根本原因在于: 对应表的字符集无法存储要插入的字符,比如汉字插入latin1编码,某些特殊字符插入gbk或者utf8等. 检查一下实际插入的字符以及对应表或者 ...
- django使用笔记
django的具体使用可以看官方手册http://djangobook.py3k.cn,这里主要记录使用django中遇到的问题. 1.中文编码问题. 因为我们用到的东西基本上都有中文,在settin ...
- DOM LOAD测试笔记
DOM时间:1823ms LOAD时间:4912ms COMP时间:5427ms 1585 4757 5650 1859 3487 3910 1600 4648 5099 1610 4428 4878 ...