微信分享接口调用

微信服务号中做运营活动,需要把页面分享到朋友圈,或者转发用户。这个功能很普遍,在写的时候有几个问题需要注意,在此记录,方便新接触的同学有个参考。

首先,如果之前没有接触过这个接口,还是要看下官方文档,有个基础的印象,链接如下:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN

接下来,可以自己试一下,如果还是有点问题,比如wx.config一直出现invalidsignature,可以来参考下我的写法。

基本的方法就是js调用微信的wx.config().以及在config参数正确的时候调用相关的onMenuShareTimeline,onMenuShareAppMessage也就是分享给朋友,分享给朋友圈。invalidsignature问题可以先在微信JS接口签名校验工具上http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign把各个参数录入进去,看看是否正确。如果正确,还报错,就说明你的url多半是错了,对此我的做法是在页面上把当前request传到后端,解析出当前的全路径url,然后再来生成signature,简单粗暴,挺有效的

我的前端页面是用velocity写的,通过springmvc来调用,页面调用以及js的写法如下

#set($weiMap=$!dataTag.getWeiMap($request,$!code))
	<input type="hidden" id="shareUrl" name="shareUrl" value='https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb7bd46a3ecfe69bb&redirect_uri=$!appTag.getAppUrl()/operate/operationShare.htm?id=$!userId&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect'/>
	<input type="hidden" id="appId" name="appId" value='$weiMap.get("appId")'/>
	<input type="hidden" id="timestamp" name="timestamp" value='$weiMap.get("timestamp")'/>
	<input type="hidden" id="nonceStr" name="nonceStr" value='$weiMap.get("nonceStr")'/>
	<input type="hidden" id="signature" name="signature" value='$weiMap.get("signature")'/>
	<input type="hidden" id="position" name="position" value='$!position'/>
	<input type="hidden" id="url" name="url" value='$weiMap.get("url")'/>
	<script src="$!appTag.getWebUrl()/js/sea.js" data-main="$!appTag.getWebUrl()/js/page/share_friend" data-config="$!appTag.getWebUrl()/js/config" type="text/javascript"></script>
</body>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
  wx.config({
	    appId: $("#appId").val(),
	    timestamp: $("#timestamp").val(),
	    nonceStr: $("#nonceStr").val(), 
	    signature: $("#signature").val(),
       jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] 
	});
wx.ready(function(){
    wx.onMenuShareAppMessage({
      title: '“sidda杯”刷牙pk赛,迪士尼门票免费送!快来给我点赞助力,我要去迪士尼!',
      desc: '我当前排名第'+$("#position").val()+'位,快来点赞帮我投票吧亲!我要去迪士尼',
      link: $("#shareUrl").val(),
      imgUrl: 'http://mengya-web.oss-cn-hangzhou.aliyuncs.com/20160815142840.jpg',
    });
      
   wx.onMenuShareTimeline({
      title: '“sidda杯”刷牙pk赛,迪士尼门票免费送!快来给我点赞助力,我要去迪士尼!',
      link: $("#shareUrl").val(),
      imgUrl: 'http://mengya-web.oss-cn-hangzhou.aliyuncs.com/20160815142840.jpg',
    });
    
  });
	</script>

我用set在页面注入了后端的方法调用$weiMap=$!dataTag.getWeiMap($request,$!code),主要用来生成weiMap这样一个对象,来给wx.config配置相应的微信验证参数

在java中生成weiMap的参数是这样写的

public Map<String, String> getWeiMap(HttpServletRequest request,String code) {
		String jsapi_ticket = weixinService.getJsapiTicket();
		Map<String, String> ret = new HashMap<String, String>();
		String nonce_str = create_nonce_str();
		String timestamp = create_timestamp();
		String string1;
		String signature = "";
		String url = getUrl(request);
		// 注意这里参数名必须全部小写,且必须有序
		string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
				+ "&timestamp=" + timestamp + "&url=" + url;
		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("appId", weixinService.getAppId());
		ret.put("nonceStr", nonce_str);
		ret.put("timestamp", timestamp);
		ret.put("signature", signature);
		ret.put("url", url);
		ret.put("jsapi_ticket", jsapi_ticket);

		return ret;
	}
public String getUrl(HttpServletRequest request){
		StringBuffer url=request.getRequestURL();
		if(StringUtils.isNotBlank(request.getQueryString())){
			url.append("?"+request.getQueryString());
		}
		return url.toString();
	}

其中getJsapiTicket这个方法主要是通过https的方式调用微信接口,我用redis缓存做了记录,代码如下,设计到https的请求实现,以及reids对应的key我就不贴出来了,大家应该有自己的方法来实现

public String getJsapiTicket() {
		String vresult = redisService.getRedis(null,
				Constant.RedisKeyEnum.WEIJSTICKET);
		if (StringUtils.isNotBlank(vresult)) {
			return vresult;
		}
		String url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+getToken()+"&type=jsapi";
		String params = null;
		try {
			String result = Https.doPost(url, params, "UTF-8", 604800, 604800);
			JSONObject jo = JSONObject.parseObject(result);
			String ticket=jo.get("ticket").toString();
			redisService.insertRedis(null, Constant.RedisKeyEnum.WEIJSTICKET, ticket,
					60);
			return ticket;
		} catch (Exception e) {
			weixinServiceLogger.error("获取微信jsticket出错 ", e);
			e.printStackTrace();
			return null;
		}
	}

注意jsticket这个方法调用微信是有次数限制的,所以大家最好缓存起来

后端的public Map<String, String> getWeiMap(HttpServletRequest request,String code)这个方法主要是用到veloctiy的toolbox这个东西来连接前后端调用的,另外对与request的调用也要在springmvc的配置veloctiy中的ViewResolver中放开,配置如下
<!-- 配置视图的显示 -->
    <bean id="ViewResolver" class="com.healthy.business.velocity.resolver.FixedVelocityLayoutViewResolver">
		<property name="order" value="10" />
		<property name="suffix" value=".vm" />
		<property name="prefix" value="screen" />
		<property name="layoutUrl"  value="layout/default.vm"/>
		<property name="exposeSpringMacroHelpers" value="true" />
		<property name="dateToolAttribute" value="dateTool" />
		<property name="numberToolAttribute" value="numberTool" />
		<property name="toolboxConfigLocation" value="WEB-INF/conf/vm-toolbox.xml" />
		<property name="contentType" value="${web.contentType}"></property>
		<property name="templateEncoding" value="UTF-8"></property>
		<property name="exposeRequestAttributes" value="true"></property>
		<property name="exposeSessionAttributes" value="true" />
		<property name="allowSessionOverride" value="true" />
    </bean>

注意dateToolAttribute,toolboxConfigLocation,exposeRequestAttributes这些配置

相关推荐