踩坑之 java微信wifi 配网airkiss

2023-11-07

最近在负责微信WiFi连接硬件设备的需求

只想说 坑 坑 坑

配网过程中一直重复报两个错 1、config:fail,Error: 系统错误,错误码:40048,invalid url domain

                                                2、config:fail,Error: 系统错误,错误码:63002,invalid signature

总之 不是报 url错误,就是报 签名无效

崩溃,经过各方大佬的指教,终于求证出来

微信配网总结:1、微信公众号配置

                          2、先获取AccessToken,通过AccessToken来请求票据jsApiTicket,最后的调用签名signature

第一步:把服务器IP地址配置到微信公众号的白名单中

第二步:接口权限中找到设备功能,确保设备功能接口已获得

第三步:配置JS接口安全域名,可以放置路径或者域名,确保txt文件可以访问到

第四步:编写Java代码

package com.weixin.wifi;

import net.sf.json.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * @author sf
 * @version 1.0
 * @date 2019/12/4 11:23
 */
@RestController
@RequestMapping("wifi")
public class Airkiss {

    static String appId="XXX";//第三方用户唯一凭证  

    public static String getAccessToken() {
        String access_token = "";
        String grant_type = "client_credential";//获取access_token填写client_credential   
        String secret="XXXX";//第三方用户唯一凭证密钥,即appsecret
        //这个url链接地址和参数皆不能变  
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+appId+"&secret="+secret;
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求  
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒  
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒  
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.fromObject(message);
            System.out.println("JSON字符串:"+demoJson);
            access_token = demoJson.getString("access_token");
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return access_token;
    }
    public static String getTicket(String access_token) {
        String ticket = null;
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";//这个url链接和参数不能变  
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求  
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒  
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒  
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.fromObject(message);
            System.out.println("jsapi字符串:"+demoJson);
            ticket = demoJson.getString("ticket");
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ticket;
    }
    public static String SHA1(String decript) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String  
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数  
            for (int i = 0; i < messageDigest.length; i++) {
            String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
            if (shaHex.length() < 2) {
            hexString.append(0);
            }
            hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
//********************************************************************************************//    
    public static String getnoncestr() {
        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串  
        return noncestr;
    }

    public static String gettimestamp() {
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳  当前时间 
        return timestamp;
    }
//********************************************************************************************//
    public static String times[] = {"0","0"};
    public static int a = 0;
    public static int b = 0;
    public static int n = 0;
    static String accessToken = null;
    static String jsapi_ticket = null;
//********************************************************************************************//    
    @RequestMapping(value = "/getSign")
    public static String[] getSignatur() {

        a = Integer.parseInt(times[1]);
        b = Integer.parseInt(times[0]);

        System.out.println("获取access时间:"+times[0]);
        System.out.println("当前获取access:"+times[1]);

        if(n == 0){//初始化获取参数
            //1、获取AccessToken 
            accessToken = getAccessToken();
            //2、获取Ticket   
            jsapi_ticket = getTicket(accessToken);
            n = 1;
        }

        if(a - b > 7000){//定时获取参数
            //1、获取AccessToken  
            String accessT = getAccessToken();
            String jsapi_t = getTicket(accessT);
            accessToken = accessT;
            jsapi_ticket = jsapi_t;
            times[0] = times[1];
        }

        //3、时间戳和随机字符串  
        String noncestr = getnoncestr();
        String timestamp = gettimestamp();
        times[1] = timestamp;

        System.out.println("accessToken:"+accessToken+"\njsapi_ticket:"+jsapi_ticket+"\n时间戳:"+timestamp+
                "\n随机字符串:"+noncestr);

        String url = "http://XXXX"; //重点:需要获取签名的页面url具体地址,例如:www.XXXX.com/wifi.html

        //5、将参数排序并拼接字符串  
        String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
        //6、将字符串进行sha1加密  
        String signature = SHA1(str);
        System.out.println("参数:"+str+"\n签名:"+signature);
        String[] sendstr = new String[4];
        sendstr[0] = appId;
        sendstr[1] = timestamp;
        sendstr[2] = noncestr;
        sendstr[3] = signature;

        return sendstr;
    }
}

这里的URL我要着重说明一下,踩坑就踩在这里了

url就是步骤五的页面地址

url为访问的页面

第五步:前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
</head>

<body>
</body>
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script src="./wifiJs/jquery-3.3.1.min.js"></script>
<script>
    var x = []
    $.ajax({
        url:"/wifi/getSign",
        type:"GET",
        dataType:"JSON",
        async:false,
        success:function(res){
            x = res
        }
    })
    console.log(location.href)
    wx.config({
        beta : true, // 开启内测接口调用,注入wx.invoke方法
        debug : false, // 开启调试模式
        appId : x[0], // 第三方app唯一标识
        timestamp : x[1], // 生成签名的时间戳
        nonceStr : x[2], // 生成签名的随机串
        signature :x[3],// 签名
        jsApiList : ['configWXDeviceWiFi'] // 需要使用的jsapi列表
    });
    var second = 5;
    wx.ready(function () {
        wx.checkJsApi({
            jsApiList: ['configWXDeviceWiFi'],
            success: function(res) {
                wx.invoke('configWXDeviceWiFi', {}, function(res){
                    err_msg = res.err_msg
                    if(err_msg == 'configWXDeviceWiFi:ok') {
        console.log('yes');
                        $('#tips').html("配置 wifi 成功,正在跳转...");
                        return;
                    } else {
                        console.log('no');
                        $('#tips').html("配置 wifi 失败,是否再次扫描");
                    }
                    console.log('configWXDeviceWiFi', res);
                });
            }
        });
    }); 
    wx.error(function(res){
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        console.log(res)
    });
    function count(){
        second--;
        $('#second').html(second);
        if(second == 0){
            //跳转到首页
            //window.location.href='/consumer/main'
        }
    }
</script>
</html>

第六步:在微信公众号——自定义菜单,找到自己的小程序,配置页面地址,页面地址为点击后要跳转的页面

以上配置完成:

在微信开发者工具中测试:测试地址为网页url地址,最后返回结果是没有此SDK或暂不支持此SDK模拟,所以在手机上测试,显示成功,可以拿个硬件连接起来测试了!!!

以上是微信配网中的踩坑经验

切记:url值得是页面访问网址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

踩坑之 java微信wifi 配网airkiss 的相关文章

  • Java(正则表达式)-获取句子中的所有单词

    我需要将 java 字符串拆分为单词数组 假设该字符串是 Hi I need to split this string into a serie s of words 目前我正在尝试使用这个String strs str split w 但
  • Linux 上的 JavaFX

    Linux x86 和 x64 上的 JavaFX 情况如何 JavaFX 应用程序可以在 Linux 操作系统上顺利执行吗 我发现了 2011 年和 2012 年的一些问题 当时应用程序不稳定 目前发布的 JFX 版本是 2 2 4 在
  • 如何从 ByteBuffer 转换为 Integer 和 String?

    我转换了一个int使用 ByteBuffer 的字节数组putInt 方法 我该如何做相反的事情 那么将这些字节转换为 int 吗 此外 我使用 String 的将字符串转换为字节数组getBytes 方法 我如何将其反过来转换 这byte
  • spring Kafka模型不在可信包中

    我正在研究微服务spring Kafka 2 1 5 and spring boot 2 0 5 第一个服务将向卡夫卡产生一些消息 第二个服务将消耗它们 在消耗时我遇到了问题 Caused by java lang IllegalArgum
  • 如何从资源服务器中的 Spring Security OAuth2 Boot 中提取声明?

    我有一个使用 Net Core 内置的授权服务器身份服务器4 https identityserver4 readthedocs io en latest 它正在按预期工作 从 Node Js 和 Net 授权客户端和资源 现在我尝试添加
  • Log4j 2.x 如何实现惰性参数求值?

    鉴于Java 参数评估机制 http docs oracle com javase specs jls se8 html jls 15 html jls 15 12 4 2 如何Log4j 2 x实施惰性评估 https logging a
  • java应用程序,线程在终止MySQL连接后挂起

    我有一些工作线程正在运行 其中包括 MySQL 和 mysql connector java 5 1 20 当我杀死一些 SQL 语句 使用 mysql 客户端的kill 连接id 时 java线程挂起 这应该抛出一些异常 jstack 打
  • Java 多态性中的字段如何工作? [复制]

    这个问题在这里已经有答案了 我正在读书面试问题 http javabypatel blogspot in 2016 04 java interview questions html关于java 发现了很好的例子 但感到困惑 因为没有很好 更
  • 识别包含本机方法实现的库文件/源

    如何识别包含本机方法实现的库文件 Ex public native String intern 我在哪里可以找到实施 source code of String intern 方法 找到了答案String intern 与快速谷歌搜索 ht
  • Finalize() 何时执行? [复制]

    这个问题在这里已经有答案了 在一次采访中我被问到 假设 JVM 在 A 类对象未被使用时运行 gc class A some code here protected void finalize code here 它是否保证finalize
  • 如何显示 javadoc 代码块中的泛型?

    我有一个 javadoc 代码块 我想在其中编写一个包含泛型的代码示例 如下所示 public interface SomeInterface
  • 将 Tango 3D 点投影到屏幕 Google Project Tango

    Project Tango 提供了点云 如何获取点云中 3D 点的像素位置 以米为单位 我尝试使用投影矩阵 但得到的值非常小 0 5 1 3 等 而不是 1234 324 以像素为单位 我包含我尝试过的代码 Get the current
  • 方法中缺少 return 语句错误

    我正在尝试编写一个返回计算机 MAC 地址字符串的静态方法 该函数本身可以在此处找到 http www mkyong com java how to get mac address in java http www mkyong com j
  • 在 libgdx 中截取屏幕截图

    我有一个应用程序 我想在其中截取游戏屏幕的屏幕截图并将其保存为图像并上传到 Facebook 我正在使用 Libgdx 我的重点是 android 谁能帮助我如何以编程方式截取游戏屏幕并将其另存为图像 现在相当容易 Libgdx提供了一个例
  • Java:当计时器处于活动状态时,JSplitPane 将顶部面板的内容复制到底部面板

    所以我有一个 JSplitPane 和两个 JPanel 一个在顶部 一个在底部 在这两个面板中 我重写了paintComponent方法并添加了我自己的图形 在底部面板中 我想添加动画 当面板不重新绘制时 这很好 但是一旦计时器 java
  • Java中ThreadFactory的使用

    有人可以简要解释一下如何以及何时使用 ThreadFactory 吗 使用和不使用 ThreadFactory 的示例可能确实有助于理解差异 Thanks 这是一种可能的用法 假设您有一个ExecutorService它执行你的Runnab
  • Apache POI:包含图表的克隆工作表

    根据众多消息来源 例如官方页面上的限制部分 http poi apache org spreadsheet limitations html 可能从 POI 处理 Excel 图表的唯一好方法是使用 Excel 文件和现有图表作为模板 并修
  • 在简历上重新加载 SharedPreferences? (或如何刷新/重新加载活动)

    当我从一项活动恢复到另一项活动时 如何重新加载 SharedPreferences 如果我继续 用户可能已经更改了设置 是否可以重新加载 SharedPreferences 或者我是否需要刷新 重新加载活动 如果 那么如何 获取和设置方式没
  • 如何配置 Spring boot 以使用两个数据库?

    我在用春季启动 2 X with 休眠5连接两个不同的 MySQL 数据库 Bar 和 Foo 在不同的服务器上 我试图列出一个实体的所有信息 自己的属性和 OneToMany and ManyToOne关系 来自 REST 控制器中的方法
  • 如何从特定偏移量的kafka主题消费到特定偏移量的数据?

    我需要消耗特定偏移量到特定结束偏移量 Consumer seek 从特定偏移量读取数据 但我需要检索从offset到tooffset的数据 任何帮助将不胜感激 提前致谢 ConsumerRecords

随机推荐

  • Qt 常用的字符转换,QString如何转换成const char类型, 转 PWCHAR wchar_t*

    常用的字符转换 日常记录 QString如何转换成const char类型 const char cmd data qstring toStdString c str qstring为待转换的qstring类型字符串 QString for
  • redis主从复制和哨兵模式

    redisi主从和哨兵模式 主从复制概扩及原理 redisi主从复制模式 redis哨兵原理 redis哨兵模式 主从复制概扩及原理 Redis主从复制是指将一个Redis实例 即主库 的数据复制到其他Redis实例 即从库 的过程 主节点
  • 一分钟了解HTTP和HTTPS协议

    很多人存在这样的疑惑就是http与https的区别 这篇文章就跟大家介绍一下 一句话总结HTTPS是身披SSL外壳的HTTP HTTPS更安全 实际使用中绝大多数的网站现在都采用的是HTTPS协议 这也是未来互联网发展的趋势 什么是协议 网
  • vue+elementui封装select-tree下拉树【单选

    组件代码
  • 鸟类识别扫一扫,AI识鸟一拍就知道鸟类信息

    随着工业化的发展 森林 湿地等生态系统逐步被开发 如何保护鸟类日益成为人们关注的话题 针对自然保护地鸟类监测面临的种类繁多 相似度高 活动范围大等痛点 快瞳科技研发上线的鸟类识别算法便致力于解决以上痛点 借助AI赋能助力生物多样性保护 快瞳
  • Linux命令之杀掉被占用的端口号

    前言 场景介绍 项目启动失败或者启动成功访问报404 很可能是访问端口被占用导致 记录一下杀死被占用端口的常用命令 共同学习 实现过程 方案1 查找被占用的端口号 netstat tln grep 8081 netstat anp grep
  • 关于Python中的可变对象与不可变对象的区别

    Python中的可变对象与不可变对象 什么是可变对象 不可变对象 可变对象 对象存放在地址中的值不会被改变 所谓的改变是创建了一块新的地址并把新的对象的值放在新地址中原来的对象并没有发生变化 不可变对象 对象存放在地址中的值会原地改变 in
  • 分享一个隐藏链接的样式

    先上效果图 再看代码
  • python3画直方图出现“Polygon‘ object has no property ‘normed”

    直方图原程序 import numpy as np import matplotlib pyplot as plt np random seed 0 mu sigma 100 20 均值和标准差 a np random normal mu
  • Linux下同一个Tomcat部署多个项目不同端口访问

    1 复制conf Catalina文件夹并命名为Catalina1 cd app tomcat8bi conf cp a Catalina Catalina1 2 复制webapps文件夹并命名为webapps1 cd app tomcat
  • openwrt--编译源码

    准备工作 首先 系统我用的是ubuntu2004 openwrt版本是github上最新版本的代码 安装需要的软件 sudo apt get install git g make libncurses5 dev subversion lib
  • H5网页等链接被微信秒封(拦截、屏蔽、和谐)后最好的解决方法

    H5网页等链接被微信秒封 拦截 屏蔽 和谐 后最好的解决方法 参考文章 1 H5网页等链接被微信秒封 拦截 屏蔽 和谐 后最好的解决方法 2 https www cnblogs com lkli p 11424598 html 备忘一下
  • Linux学习 day13之k8s基础简介

    k8s基础简介 一 Kubernetes 概述 开源的 用于管理云平台中多个主机上的容器化的应用 特点 Kubernetes 组件 Master 组件 提供集群管理控制中心 kube apiserver ETCD kube controll
  • COOKIE与SESSION的区别

    Web基础 COOKIE与SESSION的区别 一 COOKIE 1 COOKIE是什么 cookie可以理解是服务器暂存在客户端的文本信息 txt文件 2 COOKIE从哪来 cookie从服务端来 它是由服务端生成的 客户端可以清除co
  • 线上问题处理案例:出乎意料的数据库连接池

    导读 本文是线上问题处理案例系列之一 旨在通过真实案例向读者介绍发现问题 定位问题 解决问题的方法 本文讲述了从垃圾回收耗时过长的表象 逐步定位到数据库连接池保活问题的全过程 并对其中用到的一些知识点进行了总结 一 问题描述 大促期间 某接
  • 查询CPU的核数

    超线程技术就是利用特殊的硬件指令 把两个逻辑内核模拟成两个物理芯片 让单个处理器都能使用线程级并行计算 进而兼容多线程操作系统和软件 减少了CPU的闲置时间 提高的CPU的运行效率 超线程技术是在一颗CPU同时执行多个程序而共同分享一颗CP
  • java web学习心得

    时光转瞬即逝 一个学期的java web课程完美结束了 在张老师的辛苦教导下 我学到了很多知识 例如 Web应用的基本概念与系统架构 HTML界面技术 CSS技术 JavaScript脚本技术 Servlet服务器编程技术 JSP编程技术及
  • 如何使用 scikit-learn 为机器学习准备文本数据

    欢迎大家前往云 社区 获取更多腾讯海量技术实践干货哦 文本数据需要特殊处理 然后才能开始将其用于预测建模 我们需要解析文本 以删除被称为标记化的单词 然后 这些词还需要被编码为整型或浮点型 以用作机器学习算法的输入 这一过程称为特征提取 或
  • 时序预测

    时序预测 MATLAB实现HMM隐马尔可夫模型时间序列预测 目录 时序预测 MATLAB实现HMM隐马尔可夫模型时间序列预测 预测效果 基本介绍 模型描述 程序设计 学习总结 参考资料 预测效果 基本介绍 是一个双重随机的模型 以隐层状态序
  • 踩坑之 java微信wifi 配网airkiss

    最近在负责微信WiFi连接硬件设备的需求 只想说 坑 坑 坑 配网过程中一直重复报两个错 1 config fail Error 系统错误 错误码 40048 invalid url domain 2 config fail Error 系