微信分享

使用场景:wap端分享链接
官方网站:https://mp.weixin.qq.com

开发条件

  1. 申请微信公众平台账号
  2. 获取AppId,AppSecret
  3. 添加ip白名单
  4. 绑定域名并下载txt文档

配置截图
配置截图
后台开发步骤

  1. 获取access_token(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183)
  2. 获取ticket(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115)
  3. 生成签名,并向前台响应如下参数

前台开发步骤

  1. 引入js文件(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115)
  2. Ajax请求后台获取如下参数
  3. 在wx.ready中调用需要使用的接口,并给相应的参数值

注意事项

1 access_token的时效为7200s,调用接口的频次有上限,将token妥善保管。减少access_token获取的次数。
2 必须绑定域名
3 .txt文档放到域名跟目录下

package com.dsj.data.web.utils;
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.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Sign {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(Sign.class);
	
    public static void main(String[] args) {
        String jsapi_ticket = "sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg";

        // 注意 URL 一定要动态获取,不能 hardcode
        String url = "http://example.com";
        Map<String, String> ret = sign(jsapi_ticket, url);
        for (Map.Entry entry : ret.entrySet()) {
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }
    };

    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 +
                  "&timestamp=" + 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);
        LOGGER.info(" sign timestamp: {}", timestamp);
        LOGGER.info(" sign nonce_str:{}",  nonce_str);
        LOGGER.info(" sign signature:{}",  signature);
        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);
    }
}

package com.dsj.data.wap.wx;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import com.dsj.common.utils.json.JsonMapper;
import com.dsj.common.utils.redis.one.RedisPoolUtil;
import com.dsj.common.utils.spring.ConfigUtils;
import com.dsj.data.web.utils.Sign;

@Controller
@RequestMapping("weixinIndex")
public class WXShareController {

	private static final Logger LOGGER = LoggerFactory.getLogger(WXShareController.class);
	
	private RestTemplate httpClientRestTemplate = new RestTemplate();
	
	@RequestMapping("getSLBWXInfoForShare")
	@ResponseBody
	public Map<String, String> getSLBWXInfoForShare(String url) {
		url.replace("?from=singlemessage&isappinstalled=0", "");
    	Map<String, String> sign = sign(url);
    	return sign;
    }
    
    //1微信公众号需要设置白名单    2. access_token时效性为两小时,每天有请求次数限制,存放redis/session  3测试必须要有域名,且端口为80 (项目名可有可无)
    @SuppressWarnings("unchecked")
	public Map<String, String> sign(String url) {
		LOGGER.info("share sign start:{}", url );
		Map<String, String> sign = new HashMap<String, String>();
		 //String nonceStr =  "44e98c4fa5cb5c85dfff1a178673ec97";
         //String appId = "wxf750030c2d7f3ee2";
         String nonceStr = ConfigUtils.instance.getWxNonceStr();
         String appId = ConfigUtils.instance.getWxFxApi();
			String accessToken = RedisPoolUtil.get("wxAccessToken");
			String forObject = "";
			JsonMapper jsonMapper = JsonMapper.nonDefaultMapper();
			
			if (StringUtils.isBlank(accessToken)) {
				// 微信分享签名
				String refreshToken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId +"&secret=" + nonceStr;
				forObject = httpClientRestTemplate.getForObject(refreshToken, String.class, new HashMap<String, Object>());
				LOGGER.info("wei xin rollback data: {}", forObject);
				Map<String, Object> fromJson = jsonMapper.fromJson(forObject, Map.class);
				Object object = fromJson.get("access_token");
				accessToken = (String)object;
				RedisPoolUtil.setex("wxAccessToken", accessToken, 5400);//设置一个半小时时效性
				LOGGER.info("accessToken from weChet:{}", accessToken);
			}else{
				LOGGER.info("accessToken from redis:{}", accessToken);
			}
			String getTicket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ accessToken +"&type=jsapi";
			forObject = httpClientRestTemplate.getForObject(getTicket, String.class, new HashMap<String, Object>());
			Map<String, Object> fromJson = jsonMapper.fromJson(forObject, Map.class);
			String errmsg = (String)fromJson.get("errmsg");
			LOGGER.info("result:{}", errmsg);
			if (errmsg.equals("ok")) {
				String ticket = (String)fromJson.get("ticket");
				LOGGER.info("weixin share get ticket:{}", ticket);
				sign = Sign.sign(ticket, url);
				sign.put("appId", appId);
				LOGGER.info("weixin share sign end:{}", sign);
			}
		return sign;
	}
    
	
}

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="baidu-site-verification" content="GuW0deLRPn" />
	<meta charset="UTF-8">
	<title>测试支付</title>
	<meta content="支付" name="keywords">
    <meta content="测试支付" name="description">
	<#include "common/taglibs.ftl">
	<link rel="icon" href="${ctx}/static/front/img/favicon.ico" type="image/x-icon">
	<link rel="shortcut icon" href="${ctx}/static/front/img/favicon.ico" type="image/x-icon">
	<script src="${ctx }/static/front/js/jquery.js"></script>
</head>
<body>
  	<!-- 分享 -->
  	 <div class="bdsharebuttonbox" data-tag="share_1">
          <a class="bds_tsina" data-cmd="tsina"></a>
          <a class="bds_weixin" data-cmd="weixin"></a>
          <a class="bds_qzone" data-cmd="qzone"></a>
          <a class="bds_sqq" data-cmd="sqq"></a>
</body>

<script type="text/javascript">
    //分享
    var shareTitle = '分享标题';

    var shareName = '分享名称';
    //分享
    window._bd_share_config = {
        "common": {
            "bdSnsKey": {'tsina': '1546630873'},
            'bdText': shareName,
            "bdDesc": shareTitle,
            "bdMini": "2",
            'bdPic': 'http://dasouk.oss-cn-qingdao.aliyuncs.com/upload/pic/20171114104504942098.jpg',
            "bdMiniList": false,
            "bdStyle": "1",
            "bdSize": "24",
            "bdPopupOffsetLeft": "-235"
        },
        share: [{
            "bdSize": 24
        }]
    };
    with (document)0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];
    setInterval(function () {
        $("#bdshare_weixin_qrcode_dialog").css("height", "320px");
    }, 300)
</script>

<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
    $(function () {
        /* 微信分享 */
        var URL = window.location.href;
        $.ajax({
            url: "${ctx}/weixinIndex/getWXInfoForShare",
            type: "post",
            dataType: "json",
            data: {url: URL},
            success: function (data) {
                wx.config({
                    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: data.appId, // 必填,公众号的唯一标识
                    timestamp: data.timestamp, // 必填,生成签名的时间戳
                    nonceStr: data.nonceStr, // 必填,生成签名的随机串
                    signature: data.signature,// 必填,签名,见附录1
                    jsApiList: [
                        'onMenuShareAppMessage',//分享给朋友
                        'onMenuShareTimeline',//分享到朋友圈
                        'onMenuShareQQ',//分享到QQ
                        'onMenuShareQZone'//分享到QQ空间
                    ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                });
                //微信分享
                wx.ready(function () {
                    /* 分享给朋友 */
                    wx.onMenuShareAppMessage({
						title: '高超杰测试', // 分享标题
                        desc: '业绩不错!', // 分享描述
                        imgUrl: 'http://dasouk.oss-cn-qingdao.aliyuncs.com/upload/pic/20171017101400326813.png',

                        type: 'link', // 分享类型,music、video或link,不填默认为link
                        link: URL, // 分享链接
                        dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                        success: function () {
                            //alert("分享成功");

                        },
                        cancel: function () {
                            // 用户取消分享后执行的回调函数
                        }

                    });
                    /* 分享到朋友圈 */
                    wx.onMenuShareTimeline({
                        title: '123123', // 分享标题
                        desc: '1312!', // 分享描述
                        link: URL, // 分享链接
                        imgUrl: 'http://dasouk.oss-cn-qingdao.aliyuncs.com/upload/pic/20171017101400326813.png', // 分享图标
                        success: function () {


                        },
                        cancel: function () {
                            // 用户取消分享后执行的回调函数
                        }

                    });
                    /* 分享到QQ */
                    wx.onMenuShareQQ({
                        title: '123123', // 分享标题
                        desc: '123123!', // 分享描述
                        link: URL, // 分享链接
                        imgUrl: 'http://dasouk.oss-cn-qingdao.aliyuncs.com/upload/pic/20171017101400326813.png', // 分享图标
                        success: function () {


                        },
                        cancel: function () {
                            // 用户取消分享后执行的回调函数
                        }

                    });
                    /* 分享到QQ空间 */
                    wx.onMenuShareQZone({
                        title: '12312', // 分享标题
                        desc: '123123!', // 分享描述
                        link: URL, // 分享链接
                        imgUrl: 'http://dasouk.oss-cn-qingdao.aliyuncs.com/upload/pic/20171017101400326813.png', // 分享图标
                        success: function () {


                        },
                        cancel: function () {
                            // 用户取消分享后执行的回调函数
                        }
                    });

                });
            }
        })
    });
</script>
</html>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值