微信公众号自定义分享实现(开发者)

一、公众号管理,绑定域名

进入微信公众号管理,在JS接口安全域名修改出配置自己的域名。
在这里插入图片描述

二、在页面引入JS文件

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js?v=7f54"></script>

三、通过config接口注入权限验证配置

wx.config({
	    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,
	    appId: '${appId}', // 必填,公众号的唯一标识
	    timestamp: '${timestamp}', // 必填,生成签名的时间戳
	    nonceStr: '${nonceStr}', // 必填,生成签名的随机串
	    signature: '${signature}',// 必填,签名
	    jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline'] // 必填,需要使用的JS接口列表
	});

其中jsApiList表示需要使用的JS接口列表,上面“onMenuShareAppMessage”和“onMenuShareTimeline”分别是分享微信好友和分享微信朋友圈。后面第五步将会介绍在后台如何获取时间戳、随机串和签名等问题。

四、通过ready接口处理成功验证

   // 获取需要使用的相关参数
    var memberSid = "${member.memberSid}";
	var baseUrl = "${baseUrl}";
	var linkUrl = baseUrl + "/lachinHit.html?memberSid="+memberSid+"&f="+flag;
	var src =baseUrl+ "/images/activity/lachin/fenxiangPic.png"
	
	wx.ready(function(){
	wx.onMenuShareAppMessage({
		    title: '我的标题', // 分享标题
		    desc: '我的分享描述', // 分享描述
		    link: linkUrl, // 分享链接 
		    imgUrl: src, // 分享图标
		    type: '', // 分享类型,music、video或link,不填默认为link
		    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
		    success: function () {
                alert("分享微信好友成功!");
		    },
		    cancel: function () {
		     	alert('分享微信好友失败');
		    }
		});
	wx.onMenuShareTimeline({
		    title: '我的标题', // 分享标题
		    desc: '我的分享描述', // 分享描述
		    link: linkUrl, // 分享链接 
		    imgUrl: src, // 分享图标
		    type: '', // 分享类型,music、video或link,不填默认为link
		    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
		    success: function () {
                alert("分享微信好友成功!");
		    },
		    cancel: function () {
		     	alert('分享朋友圈失败');
		    }
		});
	});

五、步骤三中参数获取

1、Controller层

	JSONObject config = wxInfoService.JSConfig(request);
	model.addAttribute("member", member);
	model.addAttribute("appId", config.getString("appId"));
	model.addAttribute("timestamp", config.getString("timestamp"));
	model.addAttribute("nonceStr", config.getString("nonceStr"));
	model.addAttribute("signature", config.getString("signature"));

2、Service层方法实现

(1)首先是获取时间戳和随机串。

public JSONObject JSConfig(HttpServletRequest request) throws Exception {
        JSONObject json = new JSONObject();
        // 从配置文件中读取appid
        String appId = PropertiesLoader.get("appid");
        // 获取时间戳
        String timestamp = System.currentTimeMillis() / 1000 + "";
        // 生成随机串
        String nonceStr = CommonUtil.createNonceStr(10);
        String currentUrl = request.getRequestURL() + "";
        if (StringUtils.isNotEmpty(request.getQueryString())) {
            currentUrl = currentUrl + "?" + request.getQueryString();
        }
        // 获取签名,重要步骤
        String signature = getJSSign(nonceStr, timestamp, currentUrl);
        json.put("appId", appId);
        json.put("timestamp", timestamp);
        json.put("nonceStr", nonceStr);
        json.put("signature", signature);
        return json;
    }

(2)生成随机串方法

public static String createNonceStr(int length) {
		String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String res = "";
		for (int i = 0; i < length; i++) {
			Random rd = new Random();
			res += chars.charAt(rd.nextInt(chars.length() - 1));
		}
		return res;
	}

(3)获取签名

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

public String getJSSign(String noncestr, String timestamp, String url)
            throws Exception {
        // 获取jsapi_ticket
        String ticket = getJSTicket();
        StringBuffer buffer = new StringBuffer();
        buffer.append("jsapi_ticket=" + ticket);
        buffer.append("&");
        buffer.append("noncestr=" + noncestr);
        buffer.append("&");
        buffer.append("timestamp=" + timestamp);
        buffer.append("&");
        buffer.append("url=" + url);
        String temp = buffer.toString();
        logger.info("getJSSign获取jsapi_ticket的参数为:currentUrl=" + url +
                "---timestamp=" + timestamp + "---nonceStr=" + noncestr +
                "----jsticket=" + ticket + "-----生成的signature=" + CommonUtil.Sha1(temp));
        return CommonUtil.Sha1(temp);
    }

(4)其中获取jsapi_ticket的方法

public String getJSTicket() throws Exception {
        String ticket = null;
        try {
            ticket = shopinRedis.get(Constants.JS_TICKET_KEY);
            if (ticket != null) {
                return ticket;
            }
            // 获取token
            String token = getToken();
            // url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + token
            String url = PropertiesLoader.get("wechat_api") + PropertiesLoader.get("js_ticket") + token;
            String result = HttpUtil.Get(url);
            JSONObject json = JSONObject.parseObject(result);
            ticket = json.getString("ticket");
            // 放入缓存
            this.shopinRedis.delete(Constants.JS_TICKET_KEY);
            this.shopinRedis.set(Constants.JS_TICKET_KEY, ticket, 60 * 60 * 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ticket;
    }

(5)获取jsapi_ticket前首先获取token

public String getToken() throws Exception {
        String accessToken = null;
        try {
            accessToken = shopinRedis.get(Constants.ACCESS_TOKEN_KEY);
            if (accessToken != null) {
                return accessToken;
            }
            // 读取配置信息中配置的appid和secret
            String appid = PropertiesLoader.get("appid");
            String secret = PropertiesLoader.get("secret");
            // url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret
            String url = PropertiesLoader.get("wechat_api") + PropertiesLoader.get("access_token") + "&appid="
                    + appid + "&secret=" + secret;
            String result = HttpUtil.Get(url);
            JSONObject json = JSONObject.parseObject(result);
            accessToken = json.getString("access_token");
            // token放入缓存
            this.shopinRedis.delete(Constants.ACCESS_TOKEN_KEY);
            this.shopinRedis.set(Constants.ACCESS_TOKEN_KEY, accessToken, 60 * 60 * 2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return accessToken;
    }

(6)接获取签名中的Sha1方法

public final static String Sha1(String s) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			byte[] btInput = s.getBytes();
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("sha-1");
			// 使用指定的字节更新摘要
			mdInst.update(btInput);
			// 获得密文
			byte[] md = mdInst.digest();
			// 把密文转换成十六进制的字符串形式
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

六、总结

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值