Dart中如何将API返回JSON数组的HEX格式SSID转为UTF-8/UTF-16
问题描述
我是Dart新手,目前通过Future从API的JSON响应构建ListView,请求代码如下:
Future<List<Job>> _fetchJobs() async { final response = await http.get( Uri.parse('http://10.10.10.254/httpapi.asp?command=wlanGetApListEx')); if (response.statusCode == 200) { final List jsonResponse = json.decode(response.body)['aplist'] as List; print(jsonResponse); return jsonResponse.map((job) => new Job.fromJson(job)).toList(); } else { throw Exception('Failed to load jobs from API'); } }
API返回的JSON数据(已修正语法错误)如下:
[ { "ssid":"444A446F626C65615F322E34", "bssid":"80:3f:5d:ed:cd:f9", "rssi":42, "channel":8, "auth":"WPA2PSK", "encry":"AES", "extch":0 }, { "ssid":"426172696369632D322E3447", "bssid":"b0:76:1b:f4:55:80", "rssi":18, "channel":1, "auth":"WPA2PSK", "encry":"AES", "extch":0 }, { "ssid":"46616D696C69615F65737061727A61", "bssid":"60:32:b1:71:ce:46", "rssi":0, "channel":5, "auth":"WPA2PSK", "encry":"AES", "extch":0 }, { "ssid":"43617361204C756369616E61", "bssid":"20:ab:48:86:17:58", "rssi":0, "channel":11, "auth":"WPA2PSK", "encry":"AES", "extch":0 } ]
可以看到返回的SSID值为HEX格式,我需要将其转换为UTF-8或UTF-16格式。我尝试使用hex包,但不知道如何在这类JSON数组上实现转换。
解决方案
1. 添加hex包依赖
在pubspec.yaml的dependencies区块中添加:
dependencies: hex: ^0.2.0 # 可替换为最新版本
执行flutter pub get(Flutter项目)或dart pub get(纯Dart项目)完成依赖安装。
2. 编写十六进制转UTF-8的工具函数
创建通用解码函数,处理十六进制字符串到UTF-8的转换:
import 'dart:convert'; import 'package:hex/hex.dart'; String hexToUtf8(String hexStr) { try { List<int> bytes = HEX.decode(hexStr); return utf8.decode(bytes); } catch (e) { // 解码失败时返回原字符串,也可自定义提示文本 return hexStr; } }
3. 在JSON解析流程中处理SSID
有两种实现方式,按需选择:
方式一:在列表映射时处理
修改_fetchJobs方法,在转换每个JSON对象前先解码SSID:
import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:hex/hex.dart'; Future<List<Job>> _fetchJobs() async { final response = await http.get( Uri.parse('http://10.10.10.254/httpapi.asp?command=wlanGetApListEx')); if (response.statusCode == 200) { final List jsonResponse = json.decode(response.body)['aplist'] as List; return jsonResponse.map((jobJson) { // 替换解码后的SSID Map<String, dynamic> processedData = { ...jobJson, 'ssid': hexToUtf8(jobJson['ssid']) }; return Job.fromJson(processedData); }).toList(); } else { throw Exception('Failed to load jobs from API'); } }
方式二:在Job类的构造函数中处理
直接在Job.fromJson里完成SSID解码,保持数据流程内聚:
class Job { final String ssid; final String bssid; final int rssi; final int channel; final String auth; final String encry; final int extch; Job({ required this.ssid, required this.bssid, required this.rssi, required this.channel, required this.auth, required this.encry, required this.extch, }); factory Job.fromJson(Map<String, dynamic> json) { return Job( ssid: hexToUtf8(json['ssid']), bssid: json['bssid'], rssi: json['rssi'], channel: json['channel'], auth: json['auth'], encry: json['encry'], extch: json['extch'], ); } }
4. 验证转换效果
以第一个SSID444A446F626C65615F322E34为例,解码后会得到DJDoublea_2.4,符合预期。
内容的提问来源于stack exchange,提问作者Alejandro Carrasquero
相关产品推荐
相关产品推荐

