zoukankan      html  css  js  c++  java
  • 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只会提示一次,允许就一直允许,不允许就一直不允许了,没有反悔的机会。目前还没有很好的解决方案)

  • 相关阅读:
    Codeforces 691A Fashion in Berland
    HDU 5741 Helter Skelter
    HDU 5735 Born Slippy
    HDU 5739 Fantasia
    HDU 5738 Eureka
    HDU 5734 Acperience
    HDU 5742 It's All In The Mind
    POJ Euro Efficiency 1252
    AtCoder Beginner Contest 067 C
    AtCoder Beginner Contest 067 D
  • 原文地址:https://www.cnblogs.com/dulinan/p/12033043.html
Copyright © 2011-2022 走看看