- 浏览: 115315 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
ron.luo:
干货,必须得顶。
JAXB使用经验总结 -
csdn_zuoqiang:
能否看下DWR的配置情况?谢谢
结合webservice实现dwr推送 -
友友水:
。。。。不好意思,无心之失,删不掉前一条评论
JAXB使用经验总结 -
友友水:
[/flash][/flash][/flash][/flash ...
JAXB使用经验总结 -
lihong11:
大哥,加加注释好不?看不懂唉
小玩dwr实现服务器推送
获取微信JSAPI_TICKET
微信JSSDK签名 数据
页面jsp, 本页面上以引入方式,调起微信的分享功能
隐藏微信的分享功能
package com.mazing.wx; import com.fasterxml.jackson.core.type.TypeReference; import com.mazing.CommonConstants; import com.mazing.commons.utils.HttpClientUtils; import com.mazing.commons.utils.JsonUtils; import com.mazing.commons.utils.cfg.DesPropertiesEncoder; import com.mazing.core.remote.config.Config; import com.mazing.core.web.RestResult; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 读取微信 access token 的线程 * */ public class WxAccessTokenReaderThread extends Thread { private static final Logger logger = LoggerFactory.getLogger(WxAccessTokenReaderThread.class); private boolean running = true; /** * 获取间隔 */ private static final int INTERVAL = 2 * 60 * 1000; // access token 在 7200秒过期, private long TOKEN_TIMEOUT = 7200 * 1000L - INTERVAL; private long lastReadTime = 0L; private String appid = null; private String secret = null; /** * access token */ static volatile String wxAccessToken = ""; /** * jsapi_ticket */ static volatile String wxJsapiTicket = ""; public WxAccessTokenReaderThread() { super("WxAccessTokenReaderThread"); } public void stopRunning() { running = false; interrupt(); } @Override public void run() { logger.info("WxAccessTokenReaderThread started ..."); if (!readConfig()) { logger.error("读取配置错误,线程结束,请配置 group=weixin_mp 的内容。 "); running = false; } while (running) { long now = System.currentTimeMillis(); if (now - lastReadTime >= TOKEN_TIMEOUT) { try { readToken(); readTicket(); lastReadTime = now; } catch (Exception e) { logger.error("读取微信 access token / jsapi ticket 错误", e); } } try { sleep(INTERVAL); } catch (InterruptedException e) { break; } } logger.info("WxAccessTokenReaderThread stopped ..."); } /** * 读取配置,只读一次 * @throws Exception */ public boolean readConfig() { String json = HttpClientUtils.doGet(CommonConstants.CONFIG_DOMAIN + "/api/base/allConfigs"); // logger.info("wx#readConfig | http response | result: {}", json.substring(0, 10) + "***"); RestResult<List<Config>> result = JsonUtils.parseObject(json, new TypeReference<RestResult<List<Config>>>() { }); if (!(result.isSuccess())) { logger.warn("wx#readConfig#Failure | Failure Request | result: {}", json); return false; } final String groupCode = "weixin_mp"; DesPropertiesEncoder decoder = new DesPropertiesEncoder(); int found = 0; for (Config config : result.getObject()) { if (groupCode.equals(config.getGroupCode())) { if ("appid".equalsIgnoreCase(config.getConfigKey())) { appid = decoder.decode(config.getConfigValue()); found++; } else if ("secret".equalsIgnoreCase(config.getConfigKey())) { secret = decoder.decode(config.getConfigValue()); found++; } } if (found >= 2) break; } return found >= 2; } /** * 读取 access token */ private void readToken() { Map<String, String> params = new HashMap<>(4); params.put("grant_type", "client_credential"); params.put("appid", appid); params.put("secret", secret); String json = HttpClientUtils.doGet("https://api.weixin.qq.com/cgi-bin/token", 10000, params); if (StringUtils.isBlank(json)) { logger.error("读取微信 access token 错误"); } Map<String, Object> map = JsonUtils.parseObject(json.trim(), new TypeReference<Map<String, Object>>() { }); if (map.containsKey("access_token")) { wxAccessToken = (String) map.get("access_token"); logger.info("读取微信 access token 成功"); if (map.containsKey("expires_in")) { int expiresIn = ((Number)map.get("expires_in")).intValue(); logger.info("过期时间 (s):" + expiresIn); TOKEN_TIMEOUT = expiresIn * 1000L - INTERVAL; if (TOKEN_TIMEOUT < 1000) { TOKEN_TIMEOUT = 10 * 60 * 1000L - INTERVAL; } } } else { logger.error("读取微信 access token 错误:" + json); } } /** * 读取 jsapi_ticket */ private void readTicket() { Map<String, String> params = new HashMap<>(4); params.put("access_token", wxAccessToken); params.put("type", "jsapi"); String json = HttpClientUtils.doGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket", 10000, params); Map<String, Object> map = JsonUtils.parseObject(json.trim(), new TypeReference<Map<String, Object>>() { }); int errcode = -1; if (map.get("errcode") != null) { errcode = ((Number) map.get("errcode")).intValue(); logger.info("读取微信 jsapi_ticket 结果,errcode: {}, errmsg: {}", errcode, map.get("errmsg")); if (errcode == 0) { wxJsapiTicket = (String) map.get("ticket"); logger.info("读取微信 jsapi_ticket 成功!"); } } else { logger.error("读取微信 jsapi_ticket 错误:" + json); } } }
package com.mazing.commons.wx; import com.mazing.cfg.GlobalSetting; import com.mazing.commons.utils.HttpClientUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 获取微信 access token。 * 文档见:http://mp.weixin.qq.com/wiki/15/54ce45d8d30b6bf6758f68d2e95bc627.html * 接口:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET * 每天最多 2000 次 * @ */ public class AccessTokenCollector extends Thread { private static final Logger logger = LoggerFactory.getLogger(AccessTokenCollector.class); // true:不需要读取wx token(线程直接结束) private final boolean skip = Boolean.parseBoolean(GlobalSetting.getSysCongfig("noTokenWX")); private boolean stopped = false; /** * 间隔 */ private static final int INTERVAL = 2 * 60 * 1000; // 读取 access token 的地址 public static final String URL = "http://123.40.50.60:20090/"; public AccessTokenCollector() { super("accessTokenCollector"); } public void stopRunning() { this.stopped = true; interrupt(); } @Override public void run() { if (skip) { logger.info("mobile#wx#AccessTokenCollector | 不需要读取微信公众号Token信息"); return; } logger.info("mobile#wx#AccessTokenCollector | 读取微信公众号 token 线程启动 ..."); while (!stopped) { try { String str = HttpClientUtils.doGet(URL); str = StringUtils.trimToEmpty(str); if (StringUtils.isNotEmpty(str)) { String[] array = str.split("\\|"); WeixinAccessToken.ACCESS_TOKEN = array[0]; WeixinAccessToken.JSAPI_TICKET = array[1]; logger.info("mobile#wx#AccessTokenCollector | 读取微信公众号 token 成功"); } else { logger.error("mobile#wx#AccessTokenCollector | 读取微信公众号 token 出错,没有结果"); } } catch (Exception e) { logger.error("mobile#wx#AccessTokenCollector | 出错", e); } try { Thread.sleep(INTERVAL); } catch (InterruptedException e) { // ignore break; } } logger.info("mobile#wx#AccessTokenCollector | 读取微信公众号 token 线程结束 ..."); } }
微信JSSDK签名 数据
package com.mazing.mobile.web.utils; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mazing.CommonConstants; import com.mazing.commons.utils.JsonUtils; import com.mazing.commons.utils.cfg.DesPropertiesEncoder; import com.mazing.commons.utils.encrypt.EncryptUtil; import com.mazing.commons.wx.WeixinAccessToken; import com.mazing.core.remote.config.ConfigGroupConstants; import com.mazing.core.remote.config.ConfigRemoteService; /** * 微信分享的工具类 * * */ public class WeiXinHelper { private static final Logger logger = LoggerFactory.getLogger(WeiXinHelper.class); /** * 微信分享的attr */ public static final String WX_CONFIG_ATTR = "wxConfig"; /** * 微信appid */ private static String WX_APPID = null; // /** // * 用户的请求是否是https的(进入到nginx的是否是https)(nginx upstream是http) // */ // public static boolean httpsFromNginx(HttpServletRequest request) { // String url = request.getRequestURL().toString(); // String scheme = request.getHeader("x-forwarded-proto"); // return (url.startsWith("https://") || (StringUtils.isNotBlank(scheme)) && "https".equals(scheme)); // } /** * 检查当前的请求是否是 https 的,如果不是则重定向成为https<br> * 如果执行了重定向,返回true */ public static boolean redirectFullUrl2Https(HttpServletRequest request, HttpServletResponse response) throws IOException { String params = request.getQueryString(); String url = request.getRequestURL().toString(); String scheme = request.getHeader("x-forwarded-proto"); boolean need2https = (url.startsWith("http://") // 如果是http的请求 && (StringUtils.isBlank(scheme) || !("https".equals(scheme))));// nginx上报的不是https协议 // 重定向请求为https,并返回true if (need2https) { url = url.replaceFirst("http://", "https://"); if (params != null) url += "?" + params; response.sendRedirect(url); return true; } return false; } /** * 返回当前页面完整的 URL,包括“?”后面的参数 * * @param request * @return */ public static String getFullUrl(HttpServletRequest request) { String params = request.getQueryString(); String url = request.getRequestURL().toString(); // nginx 的 upstream配置使用的是 http,导致外部是https的请求,来到代码却是http // nginx 会带上scheme参数(443端口才设置) String scheme = request.getHeader("x-forwarded-proto"); if (StringUtils.isNotBlank(scheme) && "https".equals(scheme)) url = url.replaceFirst("http://", "https://"); if (params != null) { url += "?" + params; } return url; } public static void main(String[] args) { String url = "http://xxx.com?callback=http://123.com"; System.out.println(url.replaceFirst("http", "https")); } /** * 微信公众号的appid * * @return */ private static String getWxMpAppId() { if (WX_APPID == null) { String encryptedId = ConfigRemoteService.getConfig(ConfigGroupConstants.WEIXIN_WP, "appid"); if (encryptedId != null) { try { DesPropertiesEncoder decoder = new DesPropertiesEncoder(); WX_APPID = decoder.decode(encryptedId); } catch (Exception e) { logger.error("mobile#share#getWxMpAppId | 解密 appid 出错", e); } } else { logger.error("mobile#share#getWxMpAppId | 没有配置 group_code: {} config_key: {} !!", ConfigGroupConstants.WEIXIN_WP, "appid"); } } return WX_APPID; } /** * 微信分享的 config * * @param url 当前页面完整的地址,包括参数 * @return */ public static String getWxMpConfig(String url) { String noncestr = RandomStringUtils.random(16, CommonConstants.LETTER_NUMBER_CHARS); long timestamp = System.currentTimeMillis() / 1000; // 秒 logger.info("mobile#share#getWxMpConfig | 设置微信分享配置 |url: {}", url); String appId = getWxMpAppId(); String sourceStr = "jsapi_ticket=" + WeixinAccessToken.JSAPI_TICKET + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url; String signature = EncryptUtil.getSHA1(sourceStr).toLowerCase(); String[] jsApiList = new String[] { // "checkJsApi", // "onMenuShareTimeline", // "onMenuShareAppMessage",// "onMenuShareQQ",// "onMenuShareWeibo", // "onMenuShareQZone",// "hideAllNonBaseMenuItem",// "showAllNonBaseMenuItem" }; Map<String, Object> map = new HashMap<>(8); map.put("nonceStr", noncestr); map.put("timestamp", timestamp); map.put("appId", appId); map.put("signature", signature); map.put("debug", false); map.put("jsApiList", jsApiList); return JsonUtils.toJSONString(map); } /** * 设置微信分享JSSDK 需要的config配置信息<br> * * 凡是需要设置分享操作菜单(分享至朋友圈、QQ、微博, 或者屏蔽分享功能,只保留设置字体、刷新 等 菜单) 相关的页面, 都需要调用该方法进行config设置 * * @param request * */ public static void setWxJsConfig(HttpServletRequest request) { // 微信相关的内容 String url = WeiXinHelper.getFullUrl(request); request.setAttribute(WeiXinHelper.WX_CONFIG_ATTR, WeiXinHelper.getWxMpConfig(url)); } }
页面jsp, 本页面上以引入方式,调起微信的分享功能
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript"> // 微信分享的配置 wx.config(<c:out value="${wxConfig}" escapeXml="false"/>); wx.error(function(res) { //alert(JSON.stringify(res)); }); /** http://www.xiaomeiti.com/note/3561 **/ function WeixinShare(shareData) { this.shareData = shareData; if (wx && wx.checkJsApi) { this.shareType = "api"; this.initByAPI(); } else { this.shareType = "bridge"; this.initByBridge(); } } WeixinShare.prototype.initByAPI = function() { var me = this; wx.ready(function() { var shareData = { title : me.getParam("title"), desc : me.getParam("desc"), link : me.getParam("link"), imgUrl : me.getParam("imgUrl"), trigger : function(res) { /* this.title = me.getParam("title"); this.desc = me.getParam("desc"); this.link = me.getParam("link"); this.imgUrl = me.getParam("imgUrl"); */ } }; wx.onMenuShareAppMessage(shareData); var shareData2 = { title : me.getParam("title"), desc : me.getParam("desc"), link : me.getParam("link"), imgUrl : me.getParam("imgUrl"), trigger : function(res) { } }; var timelineTitle = me.getParam("timelineTitle"); if (timelineTitle) { shareData2.title = timelineTitle; } wx.onMenuShareTimeline(shareData2);//分享朋友圈 wx.onMenuShareQQ(shareData);//分享至QQ wx.onMenuShareWeibo(shareData);//分享到微博 wx.onMenuShareQZone(shareData);//分享到QZone //这里调用show all,是因为其他页面可能会调用了hide all(貌似是全局生效) 后跳转至 需要show all的页面 wx.showAllNonBaseMenuItem({ success : function() { //MazingEnv.log('已显示所有非基本菜单项'); } }); }); }; WeixinShare.prototype.initByBridge = function() { var me = this; document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() { window.alert('Bridge triggered.'); WeixinJSBridge.on('menu:share:appmessage', function(argv) { me.shareFriend() }); WeixinJSBridge.on('menu:share:timeline', function(argv) { me.shareTimeline() }); }, false); }; WeixinShare.prototype.getParam = function(name) { var val = this.shareData[name]; if (typeof val == "function") { return val(); } return val; }; WeixinShare.prototype.shareFriend = function() { WeixinJSBridge.invoke('sendAppMessage', { appid : this.getParam("appid"), img_url : this.getParam("imgUrl"), img_width : 120, img_height : 120, link : this.getParam("link"), title : this.getParam("title"), desc : this.getParam("desc") }, function(res) { _report('send_msg', res.err_msg); }); }; WeixinShare.prototype.shareTimeline = function() { WeixinJSBridge.invoke('shareTimeline', { appid : this.getParam("appid"), img_url : this.getParam("imgUrl"), img_width : 120, img_height : 120, link : this.getParam("link"), title : this.getParam("title"), desc : this.getParam("desc") }, function(res) { _report('timeline', res.err_msg); }); }; var wxApi = new WeixinShare(shareData); </script>
隐藏微信的分享功能
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script type="text/javascript"> // 微信分享的配置 wx.config(<c:out value="${wxConfig}" escapeXml="false"/>); wx.error(function(res) { //alert(JSON.stringify(res)); }); wx.ready(function() { // 1 判断当前版本是否支持指定 JS 接口,支持批量判断 wx.checkJsApi({ jsApiList : [ 'hideAllNonBaseMenuItem' ], success : function(res) { MazingEnv.log('当前版本支持wx JS接口'); } }); // 8.3 批量隐藏菜单项 /* wx.hideMenuItems({ menuList: [ 'menuItem:readMode', // 阅读模式 'menuItem:share:timeline', // 分享到朋友圈 'menuItem:copyUrl' // 复制链接 ], success: function (res) { alert('已隐藏“阅读模式”,“分享到朋友圈”,“复制链接”等按钮'); }, fail: function (res) { alert(JSON.stringify(res)); } }); */ // 8.5 隐藏所有非基本菜单项 wx.hideAllNonBaseMenuItem({ success : function() { MazingEnv.log('已隐藏所有非基本菜单项'); } }); }); </script>
发表评论
-
动态多数据源实现
2019-12-18 12:58 444背景: 目前基于连接了mobile库 从库的 项目(sprin ... -
java快速读取大文件
2018-02-08 11:19 370public static String readCon ... -
Netty服务构建实践
2016-05-26 11:40 731用main的形式在服务器上启动了一个netty服务,有端口有地 ... -
安全性,加密
2016-03-07 15:55 657/** * 随机字符串集 */ pri ... -
并发队列
2015-12-03 15:26 640import java.util.concurrent ... -
一致性hash算法测试
2014-12-17 18:40 1312因为用memcached集群缓存数据,所以增删服务器节点 对缓 ... -
ant脚本编译部署java工程到tomcat服务器
2013-06-28 15:35 1099<?xml version="1.0& ... -
Myeclipse反向生成pojo及hibernate映射文件(由数据库表)
2013-03-18 14:38 1086在这之前请创建一个web工程,然后右键选择myeclipse- ... -
手写比较器comparator
2012-07-12 15:47 1297项目中需要对一些数据进行排序,应用到了个比较强大的比较器,感觉 ... -
copy到粘贴板
2012-05-22 11:39 1183直接上代码,实现了IE和火狐下的copy content ... -
取两个集合的交集数据
2011-08-30 11:13 1280List<String> a = new A ... -
常用正则表达式收藏
2011-04-26 12:26 7311。^\d+$ //匹配非负整数(正整数 + 0) 2。 ... -
对日期类型与String类型之间转换方法的小结
2011-03-07 19:25 1264关于日期的方法举例程序如下: package c ... -
线程同步
2011-02-26 10:47 837转自http://www.iteye.com/topic/16 ... -
java多线程
2011-02-26 08:15 918本文转载自 http://www.iteye.com/topi ... -
对java中反射的整理
2011-02-24 20:04 894什么是Java中的类反射: ... -
关于线程----线程间的数据共享
2011-02-19 19:45 1598当多个线程的执行代码来自同一个类的run方法,既称他们共 ...
相关推荐
在本文中,我们将探讨如何在Vue项目中集成和使用微信JSSDK。微信JSSDK是微信为微信网页开发提供的一套API接口,可以让网页支持微信分享、微信支付等功能,增强用户的互动体验。下面将详细说明如何在Vue中使用微信...
该微信Jssdk调用的demo采用三层架构,并使用数据库来缓存全局jsapi_ticket,避免调用超出次数,内仅含微信分享给朋友以及分享至朋友圈两个接口的调用。内含数据库sql文件以及使用文档,代码中也有详细的注释,简单易懂...
jssdk,通过config接口注入权限验证配置java+jsp微信开发教程,功能:扫描二维码,拍照、本地选图,图片预览,上传图片,下载图片,获取当前网络状态,查看地理位置,获取当前地理位置打开地图,关键是使用JsSignUtil...
//微信上传下载媒体文件 // 这里不能加上s,不然保存不了amr文件 $url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token={$access_token}&media;_id={$media_id}"; ffmpeg下载地址 ...
微信jssdk支付代码包,微信最新发布的微信支付jssdk功能。
在“微信JSSDK-PHP版,分享朋友圈分享朋友DEMO,js-weixin-1.4.0版,有使用说明”这个压缩包中,包含了实现微信分享到朋友圈和分享给朋友的示例代码,以及版本为1.4.0的JSSDK。 1. **微信JSSDK**:JSSDK提供了多种...
由于微信jssdk文档经常升级变动,不保证本实例能正常运行,只供参考。 本实例只支持PHP运行,其它语言可以作参考。
用于记录接入微信JS-SDK的坑,以后方便查询 第一次接入公众号微信支付、分享、定位等等的坑的时候,心里是迷茫而又恐惧。因为,听说坑特别多,后来发现自己的亲身体验到了这一点。 支付的坑 1、当前URL未注册 问题:...
用户长按录音,松手后直接结束录音,结束录音后,用户可以选择重新录音、播放刚才的录音,上传录音(这里的上传录音指上传到自己服务器,上传步骤是,前端调用wx.uploadVoice,后台再到微信服务器下载音频文件,上传...
微信JSSDK调用扫一扫功能别一维码二维码。适用各种微信内页面需要调用扫一扫功能的项目,需要认证的服务号作授权设置。
微信jssdk拍照
微信JSSDK(JavaScript Software Development Kit)是微信官方推出的一款用于网页端的开发工具包,主要目的是方便开发者在网页上实现微信相关的功能,比如分享、支付、多媒体处理等。通过集成JSSDK,开发者可以更好...
使用JSSDK主要包括 1、判断当前客户端版本是否支持指定JS接口、 2、分享接口(微信认证) 3、图像接口 4、音频接口 5、智能接口(识别语音并返回结果) 6、设备信息(获取网络状态) 7、地理位置 8、界面操作 9、...
该代码已修改为thinkphp控制器,可以直接放在前台进行使用,其他框架请自行参照相关规则进行修改
自己对企业微信jssdk做的一个封装,集成了vConsole和weui,可以方便的获取当前页面的入口环境信息: isWechat //是否微信浏览器 isLoading //是否在loading状态 vConsole //vConsole对象 context //当前页面...
微信获取jssdk例子JAVA例子生成sign签名(MD5格式) 校验sign
微信JSSDK的使用首先需要注册成为微信开发者,并获取到AppID和AppSecret。AppID是应用的唯一标识,AppSecret则是用于验证身份的密钥。在ASP中,你需要编写代码来获取access_token和jsapi_ticket,这是使用JSSDK的...
官方没有asp的demo,弄了个asp版的微信jssdk
微信的分享功能,分享的时候有图片,自己做的一个demo,以后用到时候可以拿出来观看,适合初学者,自己亲测可以实现,有一个坑的地方自己的微信公众号是否有分享权限,没有怎么试都是失败的