微信实现分享转发功能
来源:互联网 发布:成都买车位划算 知乎 编辑:程序博客网 时间:2024/06/06 15:49
根据开发文档,首先看一下前端需要什么数据:
var currentUrl = window.location.href;//微信分享功能实现$.ajax({//调取接口返回验证码 type:"get", url:"http://域名/接口名", data:{'url':currentUrl}, success:function(res){ console.log(res) if(res.success==true){ //分享链接 var imgUrl = '图片地址'; var lineLink = 'http://域名/文件名/'; var descContent = "分享展示内容"; var shareTitle = '分享标题'; wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: 'wxdbcbd7962d016d0b', // 必填,公众号的唯一标识 timestamp: res.data.timestamp, // 必填,生成签名的时间戳 nonceStr: res.data.nonceStr, // 必填,生成签名的随机串 signature: res.data.signature,// 必填,签名,见附录1 jsApiList: [ 'checkJsApi', 'onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ' ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 wx.checkJsApi({ jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline','onMenuShareQQ'], // 需要检测的JS接口列表,所有JS接口列表见附录2, success: function(res) { // console.log(res); // 以键值对的形式返回,可用的api值true,不可用为false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} } }); wx.onMenuShareAppMessage({ title: shareTitle, // 分享标题 desc: descContent, // 分享描述 link: lineLink, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: imgUrl, // 分享图标 type: '', // 分享类型,music、video或link,不填默认为link dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空 success: function () { // 用户确认分享后执行的回调函数 //alert('success') }, cancel: function () { // 用户取消分享后执行的回调函数 // alert('false'); } }); wx.onMenuShareTimeline({ title: shareTitle, // 分享标题 link: lineLink, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: imgUrl, // 分享图标 success: function () { // 用户确认分享后执行的回调函数 // alert('success') }, cancel: function () { // 用户取消分享后执行的回调函数 // alert('false'); } }); wx.onMenuShareQQ({ title: shareTitle, // 分享标题 desc: descContent, // 分享描述 link: lineLink, // 分享链接 imgUrl: imgUrl, // 分享图标 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); }); wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 //alert(res); return; }); } else { // alert(res.message) return } }, error:function(){ console.log("error"); }});
通过上面的js可以看到后台需要提供三个参数
一、timestamp
根据文档得知,要想得到timestamp需要得到jsapi_ticket,而要想得到jsapi_ticket需要得到aaccess_token。
1、获取access_token
access_token有效期为7200秒,重复获取将导致上次获取的access_token失效,所以问题是如何定时获取并且把得到的数据放在本地。
1)新建一个AccessToken实体类
public class AccessToken { private String accessToken; private int expiresin; public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public int getExpiresin() { return expiresin; } public void setExpiresin(int expiresin) { this.expiresin = expiresin; }}
2)写一个servlet定时获取access_token,并配置在web.xml中
AccessTokenServlet:
@WebServlet(name = "accessTokenServlet")public class AccessTokenServlet extends HttpServlet{ private static final long serialVersionUID = 1L; private static Logger log = LoggerFactory.getLogger(WxCommonUtil.class); @Override public void init() throws ServletException { TokenThread.appId = getInitParameter("appid"); //获取servlet初始参数appid和appsecret TokenThread.appSecret = getInitParameter("appsecret"); log.info("weixin api appid:{}", TokenThread.appId); log.info("weixin api appsecret:{}", TokenThread.appSecret); if ("".equals(TokenThread.appId) || "".equals(TokenThread.appSecret)) { log.error("appid and appsecret configuration error, please check carefully."); } else { // 启动定时获取access_token的线程 new Thread(new TokenThread()).start(); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }}
web.xml配置
<servlet> <servlet-name>accessTokenServlet</servlet-name> <servlet-class>com.loan.servlet.AccessTokenServlet</servlet-class> <init-param> <param-name>appid</param-name> <param-value>你的appid</param-value> </init-param> <init-param> <param-name>appsecret</param-name> <param-value>你的appsecret</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet>
3)TokenThread类
public class TokenThread implements Runnable { private static Logger log = LoggerFactory.getLogger(TokenThread.class); public static String appId = ""; public static String appSecret= ""; public static AccessToken accessToken = null; @Override public void run() { while (true) { try { accessToken = WxCommonUtil.getToken(appId,appSecret); if (null != accessToken) { System.out.println(accessToken.getAccessToken()); Thread.sleep(7000 * 1000); //获取到access_token 休眠7000秒 } else { Thread.sleep(1000 * 3); //获取的access_token为空 休眠3秒 } } catch (Exception e) { System.out.println("发生异常:" + e.getMessage()); e.printStackTrace(); try { Thread.sleep(1000 * 10); //发生异常休眠1秒 } catch (Exception e1) { } } } }}
4)WxCommonUtil工具类
public class WxCommonUtil { private static Logger log = LoggerFactory.getLogger(WxCommonUtil.class); public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的appid&secret=你的secret"; public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; try { // 创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 设置请求方式(GET/POST) conn.setRequestMethod(requestMethod); // 当outputStr不为null时向输出流写数据 if (null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意编码格式 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 从输入流读取返回内容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; conn.disconnect(); jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { log.error("连接超时:{}", ce); } catch (Exception e) { log.error("https请求异常:{}", e); } return jsonObject; }
这样accessToken可以通过TokenThread.accessToken.getAccessToken()获取。
2、获取jsapi_ticket
/** * 获取jsapi_ticket * * @param access_token * @return */ public static String getTicket(String access_token) { String ticket = null; String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";//这个url链接和参数不能变 try { URL urlGet = new URL(url); HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); http.setRequestMethod("GET"); // 必须是get方式请求 http.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); http.setDoOutput(true); http.setDoInput(true); System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒 System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒 http.connect(); InputStream is = http.getInputStream(); int size = is.available(); byte[] jsonBytes = new byte[size]; is.read(jsonBytes); String message = new String(jsonBytes, "UTF-8"); JSONObject demoJson = JSONObject.fromObject(message); System.out.println("JSON字符串:"+demoJson); ticket = demoJson.getString("ticket"); is.close(); } catch (Exception e) { e.printStackTrace(); } return ticket; }
3、获取url
//这里URL要从前端动态获取,不能写死 String url=request.getParameter("url");
4、拼接字符串并进行sha1加密
String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url;
/** * sha1的加密算法 * * @param decript * @return */ public static String SHA1(String decript) { String signature=""; try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(decript.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); return signature; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } /** * 进制转换 * @param hash * @return */ public 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; }
这样一系列步骤之后就可以得到signature。
二、timestamp
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
三、nonceStr
String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
这样就能得到三个参数啦。
最后是总的controller:
@RequestMapping(value = "/sign",method = RequestMethod.GET,produces = {"application/json;charset=UTF-8"}) @ResponseBody public ObjectOutput sign(HttpServletRequest request, HttpServletResponse response, HttpSession session){ Hashtable hashtable = new Hashtable(); //1、获取accessToken String accessToken= TokenThread.accessToken.getAccessToken(); //2、获取Ticket String jsapi_ticket=WxCommonUtil.getTicket(accessToken); //3、时间戳和随机字符串 String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16); String timestamp = String.valueOf(System.currentTimeMillis() / 1000); //4、获取url String url=request.getParameter("url"); //5、讲参数排序并拼接字符串 String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url; //6、将字符串进行sha1加密 String signature =WxCommonUtil.SHA1(str); hashtable.put("signature",signature); hashtable.put("timestamp",timestamp); hashtable.put("nonceStr",noncestr); hashtable.put("url",url); output = Format.output(true, Constant.Success, hashtable, ""); return output; }
阅读全文
0 0
- 微信实现分享转发功能
- 微信转发(分享)功能
- 微信分享功能实现
- 分享转发功能如何实现?
- iOS微信分享功能简单实现
- IOS微信分享功能简单实现
- iOS微信分享功能实现
- AndroidStudio怎么实现微信分享功能
- 微信sdk分享功能实现
- 微信自带分享功能实现
- 微信JS-SDK实现分享功能
- 微信分享功能的实现
- JSSDK实现微信分享功能
- ShareSDK接入实现微信分享功能
- 微信分享功能
- 微信分享功能
- 微信分享功能
- 微信分享功能
- autodesk backburne卸载问题
- sqlite基础一
- Dubbo与Zookeeper、Spring整合和使用
- ScrollView反弹效果 仿小米私密短信效果 android布局可滚动
- python遍历目录文件
- 微信实现分享转发功能
- iOS 直接改变.html后缀的链接所对应的html页面样式,并获取html的标题,图片地址,id,内容
- 第十四章——UINavigationController
- 博客添加浮动目录
- react-router 实例
- java枚举类详解
- 计算最小公倍数
- 拟合数据时报错Number of calls to function has reached maxfev = 1000
- 纯虚函数与抽象基类