java 生成js接口签名 页面调用JS-SDK

如果要使用微信公众平台的网页开发,首先要生成签名,其算法也在官方的wiki说明了,网上也有PHP版本,在这里写一下java的生成版本:

1.因为保密需要,把关键参数隐去了,但签名与公众号接入差不多,只是参数个数变了,下面是参考代码

package cn.xdf.wlyy.controller;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import cn.xdf.wlyy.util.HttpUtils;
import cn.xdf.wlyy.util.IdUtils;

import com.alibaba.fastjson.JSONObject;

@Controller
@RequestMapping(value = "/test")
public class TestController {
	
	private static String jsToken = null;

	private static String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}
	
	private static String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];

		String s = new String(tempArr);
		return s;
	}
	
	@RequestMapping(value = "/testpage")
	public ModelAndView page(ModelAndView mav) {
		String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
		String accessTokenResult = HttpUtils.get(accessTokenUrl);
		JSONObject accessJsonObject = JSONObject.parseObject(accessTokenResult);
		String accessToken = accessJsonObject.getString("access_token");
		
		String jsTokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
		String jsTokenResult = HttpUtils.get(jsTokenUrl.replace("ACCESS_TOKEN", accessToken));
		
		JSONObject jsTokenJsonObject = JSONObject.parseObject(jsTokenResult);
		
		if (jsTokenJsonObject != null) {
			int errcode = jsTokenJsonObject.getInteger("errcode");
			if (errcode == 0) {
				jsToken = jsTokenJsonObject.getString("ticket");
			}
		}
		
		String url = "http://xxx.vicp.cc/wechatserver/test/testpage";//因为要使用微信客户微访问本地环境,这里面使用了花生壳做内网映射
		String timestamp = String.valueOf(new Date().getTime() / 1000);
		String noncestr = IdUtils.getId();
		String jsapi_ticket = jsToken;
		
		String str1 = "noncestr=" + noncestr;
		String str2 = "jsapi_ticket=" + jsapi_ticket;
		String str3 = "timestamp=" + timestamp;
		String str4 = "url=" + url;
		
		String[] paramArr = new String[] { str1, str2, str3, str4 };
		Arrays.sort(paramArr);

		// 将排序后的结果拼接成一个字符串
		String content = paramArr[0].concat("&").concat(paramArr[1]).concat("&").concat(paramArr[2]).concat("&").concat(paramArr[3]);
		String signature = null;
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			// 对接后的字符串进行sha1加密
			byte[] digest = md.digest(content.toString().getBytes());
			signature = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		/*appId: '', // 必填,公众号的唯一标识
	    timestamp: , // 必填,生成签名的时间戳
	    nonceStr: '', // 必填,生成签名的随机串
	    signature: '',// 必填,签名
	    jsApiList: [] // 必填,需要使用的JS接口列表
*/		
		mav.addObject("appId", "wxxxxxxxxxxxxxxxxxxxx");
		mav.addObject("timestamp", timestamp);
		mav.addObject("nonceStr", noncestr);
		mav.addObject("signature", signature);
		
		mav.setViewName("testPage");
		return mav;
	}
	
}

2.而在页面中,是直接访问1中的controller,跳转到这个页面,然后直接把appId/timestamp/nonceStr/signatrue等参数返回给页面,让页面调用,页面如下:

<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport"
	content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="description" content="description about your site" />
<meta name="keywords" content="" />
<meta name="author" content="ZTApps" />
<script src="<%=basePath%>/static/js/jquery-1.11.2.min.js"></script> 
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> 
<title>测试页面</title>
</head>

<body>

</body>
<script>
	$(function() {
		var appId = '${appId}';
		var timestamp = ${timestamp};
		var nonceStr = '${nonceStr}';
		var signature = '${signature}';
		wx.config({
		    debug : true,
		    appId : appId,
		    timestamp : timestamp,
		    nonceStr : nonceStr,
		    signature : signature,
		    jsApiList : ['getLocation']
		});
		
		wx.ready(function(){
			wx.getLocation({
				type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
				success: function (res) {
					var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
					var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
					var speed = res.speed; // 速度,以米/每秒计
					var accuracy = res.accuracy; // 位置精度
					alert("纬度:" + latitude);
					alert("经度:" + longitude);
					alert("速度:" + speed);
					alert("accuracy:" + accuracy);
				}
			});
		});
		
	});
</script>
</html>

上面主要是想验证签名这个参数是否生成的正确,并通过调用地址位置的接口wx.getLocation来测试是否获取到了位置。

(因为对浏览器内置的js定位很苦恼,使用android手机,在提示不允许使用位置后,下次还会有提示消息,而允许后下次就不会再有提示信息了;而用ios只会提示一次,允许就一直允许,不允许就一直不允许了,没有反悔的机会。目前还没有很好的解决方案)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值