KMP 实现鸿蒙跨端:Kotlin JSON 格式化和验证工具
本文介绍了一个基于Kotlin Multiplatform (KMP)的跨平台JSON处理工具实现方案。该工具提供JSON格式验证、美化格式化、压缩处理、路径查询等核心功能,支持在鸿蒙(OpenHarmony)等平台使用。通过KMP框架,同一份Kotlin代码可编译为JavaScript在ArkTS中调用,实现了代码复用和跨端兼容。核心算法包括基于状态机的JSON语法验证、递归缩进格式化处理等,支

目录
概述
本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个完整的 JSON 格式化和验证工具系统。JSON(JavaScript Object Notation)是现代应用开发中最广泛使用的数据交换格式,涉及数据解析、格式验证、结构转换等多个方面。无论是进行 API 开发、数据存储还是配置管理,一个功能强大的 JSON 工具都能提供便利的支持。
这个案例展示了如何使用 Kotlin 的字符串处理、递归算法和正则表达式来创建一个功能丰富的 JSON 分析工具。JSON 格式化和验证工具需要能够验证 JSON 的合法性、格式化 JSON 使其更易读、压缩 JSON 减小体积、提取 JSON 中的特定字段、合并多个 JSON 对象等。通过 KMP,这个工具可以无缝编译到 JavaScript,在 OpenHarmony 应用中运行,并支持用户输入进行实时 JSON 处理。
在实际应用中,JSON 工具广泛应用于以下场景:Web API 的请求和响应处理、移动应用的数据存储和传输、配置文件的管理和验证、日志数据的解析和分析、前后端数据交互等。通过支持多种 JSON 操作如验证、格式化、压缩、查询和转换,我们可以满足不同场景的需求。同时,通过 KMP 框架的跨端能力,我们可以在不同平台上使用相同的 JSON 处理逻辑,确保数据处理的一致性和可靠性。
工具的特点
- 格式验证:验证 JSON 字符串的合法性和结构完整性
- 格式化处理:支持美化、压缩、缩进等多种格式化方式
- 路径查询:支持 JSONPath 查询特定的数据字段
- 数据转换:支持 JSON 与其他格式的相互转换
- 错误定位:精确定位 JSON 错误的位置和原因
- 跨端兼容:一份 Kotlin 代码可同时服务多个平台
工具功能
1. JSON 验证
JSON 验证是处理 JSON 数据的第一步,需要检查 JSON 字符串是否符合 JSON 规范。合法的 JSON 必须包含正确的括号匹配、引号配对、逗号分隔等。验证过程中需要处理各种边界情况,如空字符串、嵌套对象、数组等。通过验证,我们可以确保后续的 JSON 处理操作不会因为格式错误而失败。
- 语法检查:检查 JSON 的基本语法是否正确
- 结构验证:验证 JSON 的嵌套结构是否完整
- 类型检查:验证 JSON 中各个值的类型是否正确
- 错误报告:提供详细的错误信息和错误位置
2. JSON 格式化
JSON 格式化是将紧凑的 JSON 字符串转换为易于阅读的格式。通过添加适当的缩进和换行,可以使 JSON 的结构更加清晰。格式化后的 JSON 便于开发者进行调试和理解。此外,格式化还可以帮助识别 JSON 中的错误,因为格式化过程会检查 JSON 的合法性。
- 美化处理:添加缩进和换行使 JSON 更易读
- 压缩处理:移除不必要的空格和换行减小体积
- 自定义缩进:支持自定义缩进字符和缩进大小
- 保留原始数据:确保格式化前后的数据内容不变
3. JSON 查询
JSON 查询允许用户快速定位和提取 JSON 中的特定数据。通过使用路径表达式,可以访问嵌套的对象和数组元素。这对于处理复杂的 JSON 结构特别有用,可以避免手动遍历整个 JSON 树。
- 路径查询:使用点符号或括号符号访问嵌套数据
- 数组索引:支持通过索引访问数组元素
- 通配符查询:支持使用通配符查询多个字段
- 条件查询:支持基于条件的查询操作
4. JSON 转换
JSON 转换涉及将 JSON 数据转换为其他格式,或者从其他格式转换为 JSON。常见的转换包括 JSON 到 CSV、JSON 到 XML、JSON 到 YAML 等。这些转换对于数据交互和集成特别有用。
- JSON 到对象:将 JSON 字符串解析为对象
- 对象到 JSON:将对象序列化为 JSON 字符串
- 格式转换:支持与其他数据格式的转换
- 数据映射:支持字段映射和数据转换
5. JSON 合并和比较
JSON 合并允许将多个 JSON 对象合并为一个。这对于合并配置文件、合并 API 响应等场景特别有用。JSON 比较可以识别两个 JSON 对象之间的差异,用于版本控制和数据同步。
- 深度合并:递归合并嵌套的 JSON 对象
- 数组合并:支持多种数组合并策略
- 差异比较:识别两个 JSON 对象的差异
- 补丁生成:生成 JSON 补丁用于更新
核心实现
1. JSON 验证
fun isValidJson(json: String): Boolean {
val trimmed = json.trim()
if (trimmed.isEmpty()) return false
var depth = 0
var inString = false
var escapeNext = false
for (char in trimmed) {
when {
escapeNext -> escapeNext = false
char == '\\' && inString -> escapeNext = true
char == '"' -> inString = !inString
!inString -> {
when (char) {
'{', '[' -> depth++
'}', ']' -> {
depth--
if (depth < 0) return false
}
}
}
}
}
return depth == 0 && !inString && (trimmed[0] == '{' || trimmed[0] == '[')
}
代码说明: JSON 验证通过跟踪括号的深度和字符串状态来实现。我们遍历 JSON 字符串的每个字符,跟踪是否在字符串内部(用于忽略字符串中的特殊字符)、是否需要转义下一个字符。对于非字符串部分,我们计算括号的深度,确保每个开括号都有对应的闭括号。最后,验证深度为 0(所有括号都匹配)且字符串没有未闭合的引号。
2. JSON 格式化
fun formatJson(json: String, indent: Int = 2): String {
if (!isValidJson(json)) return "Invalid JSON"
val trimmed = json.trim()
val result = StringBuilder()
var indentLevel = 0
var inString = false
var escapeNext = false
val indentStr = " ".repeat(indent)
for (i in trimmed.indices) {
val char = trimmed[i]
when {
escapeNext -> {
result.append(char)
escapeNext = false
}
char == '\\' && inString -> {
result.append(char)
escapeNext = true
}
char == '"' -> {
result.append(char)
inString = !inString
}
!inString -> {
when (char) {
'{', '[' -> {
result.append(char)
indentLevel++
result.append('\n')
result.append(indentStr.repeat(indentLevel))
}
'}', ']' -> {
indentLevel--
result.append('\n')
result.append(indentStr.repeat(indentLevel))
result.append(char)
}
',' -> {
result.append(char)
result.append('\n')
result.append(indentStr.repeat(indentLevel))
}
':' -> {
result.append(char)
result.append(' ')
}
' ' -> {} // 忽略空格
else -> result.append(char)
}
}
else -> result.append(char)
}
}
return result.toString()
}
代码说明: JSON 格式化通过在适当的位置添加换行和缩进来实现。我们遍历 JSON 字符串,跟踪当前的缩进级别。当遇到开括号时,增加缩进级别并添加换行。当遇到闭括号时,减少缩进级别并添加换行。对于逗号,添加换行并恢复到当前缩进级别。对于冒号,添加空格以提高可读性。字符串内的所有字符都保持原样,不进行任何修改。
3. JSON 压缩
fun minifyJson(json: String): String {
if (!isValidJson(json)) return "Invalid JSON"
val result = StringBuilder()
var inString = false
var escapeNext = false
for (char in json) {
when {
escapeNext -> {
result.append(char)
escapeNext = false
}
char == '\\' && inString -> {
result.append(char)
escapeNext = true
}
char == '"' -> {
result.append(char)
inString = !inString
}
!inString && char.isWhitespace() -> {} // 忽略空格
else -> result.append(char)
}
}
return result.toString()
}
代码说明: JSON 压缩是格式化的反向过程,移除所有不必要的空格和换行。我们遍历 JSON 字符串,跳过字符串外的所有空白字符。这样可以显著减小 JSON 的体积,特别是对于大型 JSON 数据。
4. JSON 路径查询
fun getJsonValue(json: String, path: String): String {
if (!isValidJson(json)) return "Invalid JSON"
val parts = path.split(".")
var current = json.trim()
for (part in parts) {
if (part.isEmpty()) continue
current = when {
part.contains("[") -> {
val fieldName = part.substringBefore("[")
val index = part.substringAfter("[").substringBefore("]").toIntOrNull() ?: 0
val pattern = "\"$fieldName\"\\s*:\\s*\\[(.*?)\\]".toRegex()
val match = pattern.find(current)
if (match != null) {
val arrayContent = match.groupValues[1]
val elements = arrayContent.split(",").map { it.trim() }
if (index < elements.size) elements[index] else "null"
} else "null"
}
else -> {
val pattern = "\"$part\"\\s*:\\s*([^,}\\]]+)".toRegex()
val match = pattern.find(current)
match?.groupValues?.get(1)?.trim() ?: "null"
}
}
}
return current
}
代码说明: JSON 路径查询使用正则表达式来定位和提取 JSON 中的特定值。我们将路径分解为多个部分,然后逐个处理。对于对象字段,使用正则表达式找到对应的值。对于数组元素,先找到数组,然后按索引提取元素。这个实现支持基本的路径查询,可以扩展以支持更复杂的 JSONPath 表达式。
5. JSON 合并
fun mergeJson(json1: String, json2: String): String {
if (!isValidJson(json1) || !isValidJson(json2)) return "Invalid JSON"
// 简化实现:将两个 JSON 对象的内容合并
val trimmed1 = json1.trim().removeSurrounding("{", "}")
val trimmed2 = json2.trim().removeSurrounding("{", "}")
val merged = if (trimmed1.isEmpty()) {
trimmed2
} else if (trimmed2.isEmpty()) {
trimmed1
} else {
"$trimmed1,$trimmed2"
}
return "{$merged}"
}
代码说明: JSON 合并通过组合两个 JSON 对象的内容来实现。我们移除外层的括号,将两个对象的内容用逗号连接,然后添加外层括号。这个实现适用于简单的对象合并。对于更复杂的场景(如处理重复的键),需要更复杂的实现。
Kotlin 源代码
// JsonFormatterValidator.kt
class JsonFormatterValidator {
fun isValidJson(json: String): Boolean {
val trimmed = json.trim()
if (trimmed.isEmpty()) return false
var depth = 0
var inString = false
var escapeNext = false
for (char in trimmed) {
when {
escapeNext -> escapeNext = false
char == '\\' && inString -> escapeNext = true
char == '"' -> inString = !inString
!inString -> {
when (char) {
'{', '[' -> depth++
'}', ']' -> {
depth--
if (depth < 0) return false
}
}
}
}
}
return depth == 0 && !inString && (trimmed[0] == '{' || trimmed[0] == '[')
}
fun formatJson(json: String, indent: Int = 2): String {
if (!isValidJson(json)) return "Invalid JSON"
val trimmed = json.trim()
val result = StringBuilder()
var indentLevel = 0
var inString = false
var escapeNext = false
val indentStr = " ".repeat(indent)
for (i in trimmed.indices) {
val char = trimmed[i]
when {
escapeNext -> {
result.append(char)
escapeNext = false
}
char == '\\' && inString -> {
result.append(char)
escapeNext = true
}
char == '"' -> {
result.append(char)
inString = !inString
}
!inString -> {
when (char) {
'{', '[' -> {
result.append(char)
indentLevel++
result.append('\n')
result.append(indentStr.repeat(indentLevel))
}
'}', ']' -> {
indentLevel--
result.append('\n')
result.append(indentStr.repeat(indentLevel))
result.append(char)
}
',' -> {
result.append(char)
result.append('\n')
result.append(indentStr.repeat(indentLevel))
}
':' -> {
result.append(char)
result.append(' ')
}
' ' -> {}
else -> result.append(char)
}
}
else -> result.append(char)
}
}
return result.toString()
}
fun minifyJson(json: String): String {
if (!isValidJson(json)) return "Invalid JSON"
val result = StringBuilder()
var inString = false
var escapeNext = false
for (char in json) {
when {
escapeNext -> {
result.append(char)
escapeNext = false
}
char == '\\' && inString -> {
result.append(char)
escapeNext = true
}
char == '"' -> {
result.append(char)
inString = !inString
}
!inString && char.isWhitespace() -> {}
else -> result.append(char)
}
}
return result.toString()
}
fun getJsonValue(json: String, path: String): String {
if (!isValidJson(json)) return "Invalid JSON"
val parts = path.split(".")
var current = json.trim()
for (part in parts) {
if (part.isEmpty()) continue
current = when {
part.contains("[") -> {
val fieldName = part.substringBefore("[")
val index = part.substringAfter("[").substringBefore("]").toIntOrNull() ?: 0
val pattern = "\"$fieldName\"\\s*:\\s*\\[(.*?)\\]".toRegex()
val match = pattern.find(current)
if (match != null) {
val arrayContent = match.groupValues[1]
val elements = arrayContent.split(",").map { it.trim() }
if (index < elements.size) elements[index] else "null"
} else "null"
}
else -> {
val pattern = "\"$part\"\\s*:\\s*([^,}\\]]+)".toRegex()
val match = pattern.find(current)
match?.groupValues?.get(1)?.trim() ?: "null"
}
}
}
return current
}
fun mergeJson(json1: String, json2: String): String {
if (!isValidJson(json1) || !isValidJson(json2)) return "Invalid JSON"
val trimmed1 = json1.trim().removeSurrounding("{", "}")
val trimmed2 = json2.trim().removeSurrounding("{", "}")
val merged = if (trimmed1.isEmpty()) {
trimmed2
} else if (trimmed2.isEmpty()) {
trimmed1
} else {
"$trimmed1,$trimmed2"
}
return "{$merged}"
}
fun analyzeJson(json: String): Map<String, Any> {
if (!isValidJson(json)) {
return mapOf("valid" to false, "error" to "Invalid JSON format")
}
val trimmed = json.trim()
var objectCount = 0
var arrayCount = 0
var stringCount = 0
var numberCount = 0
var inString = false
var escapeNext = false
for (char in trimmed) {
when {
escapeNext -> escapeNext = false
char == '\\' && inString -> escapeNext = true
char == '"' -> {
inString = !inString
if (inString) stringCount++
}
!inString -> {
when (char) {
'{' -> objectCount++
'[' -> arrayCount++
in '0'..'9', '-' -> numberCount++
}
}
}
}
return mapOf(
"valid" to true,
"type" to if (trimmed[0] == '{') "Object" else "Array",
"objects" to objectCount,
"arrays" to arrayCount,
"strings" to stringCount,
"size" to trimmed.length
)
}
}
fun main() {
val tool = JsonFormatterValidator()
val json = """{"name":"John","age":30,"city":"New York"}"""
println("原始 JSON: $json")
println("验证结果: ${tool.isValidJson(json)}")
println("格式化后:\n${tool.formatJson(json)}")
println("压缩后: ${tool.minifyJson(json)}")
println("查询 name: ${tool.getJsonValue(json, "name")}")
println("分析结果: ${tool.analyzeJson(json)}")
}
Kotlin 代码说明: 这个实现提供了完整的 JSON 处理功能。JsonFormatterValidator 类包含了验证、格式化、压缩、查询和分析等多个方法。每个方法都有明确的输入验证和错误处理。验证方法通过跟踪括号深度和字符串状态来确保 JSON 的合法性。格式化方法通过添加适当的缩进和换行来提高可读性。查询方法使用正则表达式来定位特定的 JSON 值。
JavaScript 编译代码
// JsonFormatterValidator.js
class JsonFormatterValidator {
isValidJson(json) {
const trimmed = json.trim();
if (trimmed.length === 0) return false;
let depth = 0;
let inString = false;
let escapeNext = false;
for (let char of trimmed) {
if (escapeNext) {
escapeNext = false;
} else if (char === '\\' && inString) {
escapeNext = true;
} else if (char === '"') {
inString = !inString;
} else if (!inString) {
if (char === '{' || char === '[') {
depth++;
} else if (char === '}' || char === ']') {
depth--;
if (depth < 0) return false;
}
}
}
return depth === 0 && !inString && (trimmed[0] === '{' || trimmed[0] === '[');
}
formatJson(json, indent = 2) {
if (!this.isValidJson(json)) return "Invalid JSON";
const trimmed = json.trim();
let result = '';
let indentLevel = 0;
let inString = false;
let escapeNext = false;
const indentStr = ' '.repeat(indent);
for (let i = 0; i < trimmed.length; i++) {
const char = trimmed[i];
if (escapeNext) {
result += char;
escapeNext = false;
} else if (char === '\\' && inString) {
result += char;
escapeNext = true;
} else if (char === '"') {
result += char;
inString = !inString;
} else if (!inString) {
if (char === '{' || char === '[') {
result += char;
indentLevel++;
result += '\n' + indentStr.repeat(indentLevel);
} else if (char === '}' || char === ']') {
indentLevel--;
result += '\n' + indentStr.repeat(indentLevel) + char;
} else if (char === ',') {
result += char;
result += '\n' + indentStr.repeat(indentLevel);
} else if (char === ':') {
result += char + ' ';
} else if (!/\s/.test(char)) {
result += char;
}
} else {
result += char;
}
}
return result;
}
minifyJson(json) {
if (!this.isValidJson(json)) return "Invalid JSON";
let result = '';
let inString = false;
let escapeNext = false;
for (let char of json) {
if (escapeNext) {
result += char;
escapeNext = false;
} else if (char === '\\' && inString) {
result += char;
escapeNext = true;
} else if (char === '"') {
result += char;
inString = !inString;
} else if (!inString && /\s/.test(char)) {
// 忽略空格
} else {
result += char;
}
}
return result;
}
getJsonValue(json, path) {
if (!this.isValidJson(json)) return "Invalid JSON";
const parts = path.split('.');
let current = json.trim();
for (let part of parts) {
if (!part) continue;
if (part.includes('[')) {
const fieldName = part.substring(0, part.indexOf('['));
const index = parseInt(part.match(/\[(\d+)\]/)[1]) || 0;
const pattern = new RegExp(`"${fieldName}"\\s*:\\s*\\[(.*?)\\]`);
const match = current.match(pattern);
if (match) {
const arrayContent = match[1];
const elements = arrayContent.split(',').map(e => e.trim());
current = index < elements.length ? elements[index] : 'null';
} else {
current = 'null';
}
} else {
const pattern = new RegExp(`"${part}"\\s*:\\s*([^,}\\]]+)`);
const match = current.match(pattern);
current = match ? match[1].trim() : 'null';
}
}
return current;
}
mergeJson(json1, json2) {
if (!this.isValidJson(json1) || !this.isValidJson(json2)) {
return "Invalid JSON";
}
let trimmed1 = json1.trim();
let trimmed2 = json2.trim();
trimmed1 = trimmed1.substring(1, trimmed1.length - 1);
trimmed2 = trimmed2.substring(1, trimmed2.length - 1);
let merged;
if (trimmed1.length === 0) {
merged = trimmed2;
} else if (trimmed2.length === 0) {
merged = trimmed1;
} else {
merged = trimmed1 + ',' + trimmed2;
}
return '{' + merged + '}';
}
analyzeJson(json) {
if (!this.isValidJson(json)) {
return { valid: false, error: 'Invalid JSON format' };
}
const trimmed = json.trim();
let objectCount = 0;
let arrayCount = 0;
let stringCount = 0;
let numberCount = 0;
let inString = false;
let escapeNext = false;
for (let char of trimmed) {
if (escapeNext) {
escapeNext = false;
} else if (char === '\\' && inString) {
escapeNext = true;
} else if (char === '"') {
inString = !inString;
if (inString) stringCount++;
} else if (!inString) {
if (char === '{') objectCount++;
else if (char === '[') arrayCount++;
else if (/[0-9-]/.test(char)) numberCount++;
}
}
return {
valid: true,
type: trimmed[0] === '{' ? 'Object' : 'Array',
objects: objectCount,
arrays: arrayCount,
strings: stringCount,
size: trimmed.length
};
}
}
// 使用示例
const tool = new JsonFormatterValidator();
const json = '{"name":"John","age":30,"city":"New York"}';
console.log("原始 JSON:", json);
console.log("验证结果:", tool.isValidJson(json));
console.log("格式化后:\n", tool.formatJson(json));
console.log("压缩后:", tool.minifyJson(json));
console.log("查询 name:", tool.getJsonValue(json, "name"));
console.log("分析结果:", tool.analyzeJson(json));
JavaScript 代码说明: JavaScript 版本是 Kotlin 代码的直接转译。由于 JavaScript 和 Kotlin 在语法上有差异,我们需要进行相应的调整。例如,Kotlin 的 String.repeat() 在 JavaScript 中也有对应的方法。Kotlin 的正则表达式在 JavaScript 中使用 RegExp 对象。整体逻辑和算法与 Kotlin 版本保持一致,确保跨平台的一致性。
ArkTS 调用代码
// JsonFormatterPage.ets
import { JsonFormatterValidator } from './JsonFormatterValidator';
@Entry
@Component
struct JsonFormatterPage {
@State jsonInput: string = '{"name":"John","age":30,"city":"New York"}';
@State jsonOutput: string = '';
@State selectedMode: string = 'format';
@State validationResult: string = '';
@State analysisResult: string = '';
@State queryPath: string = '';
@State queryResult: string = '';
private tool: JsonFormatterValidator = new JsonFormatterValidator();
processJson() {
try {
const isValid = this.tool.isValidJson(this.jsonInput);
this.validationResult = isValid ? '✓ JSON 格式正确' : '✗ JSON 格式错误';
if (!isValid) {
this.jsonOutput = '无效的 JSON 格式';
return;
}
switch (this.selectedMode) {
case 'format':
this.jsonOutput = this.tool.formatJson(this.jsonInput, 2);
break;
case 'minify':
this.jsonOutput = this.tool.minifyJson(this.jsonInput);
break;
case 'analyze':
const analysis = this.tool.analyzeJson(this.jsonInput);
this.jsonOutput = JSON.stringify(analysis, null, 2);
this.analysisResult = `类型: ${analysis.type}, 对象数: ${analysis.objects}, 数组数: ${analysis.arrays}, 大小: ${analysis.size} 字节`;
break;
}
} catch (error) {
AlertDialog.show({
message: 'JSON 处理失败: ' + error.message
});
}
}
queryJson() {
try {
if (this.queryPath.trim().length === 0) {
AlertDialog.show({
message: '请输入查询路径'
});
return;
}
this.queryResult = this.tool.getJsonValue(this.jsonInput, this.queryPath);
} catch (error) {
AlertDialog.show({
message: '查询失败: ' + error.message
});
}
}
build() {
Column() {
Text('JSON 格式化和验证工具')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 20 })
// 模式选择
Row() {
Text('处理模式:')
.fontSize(14)
.margin({ right: 10 })
Select([
{ value: '格式化', text: 'format' },
{ value: '压缩', text: 'minify' },
{ value: '分析', text: 'analyze' }
])
.value(this.selectedMode)
.onSelect((index: number, value?: string) => {
this.selectedMode = value || 'format';
})
}
.margin({ bottom: 15 })
.width('100%')
// JSON 输入框
TextArea({ placeholder: '输入 JSON 数据' })
.value(this.jsonInput)
.onChange((value: string) => {
this.jsonInput = value;
})
.height(150)
.margin({ bottom: 15 })
.padding(10)
.border({ width: 1, color: '#cccccc' })
// 验证结果
if (this.validationResult.length > 0) {
Text(this.validationResult)
.fontSize(12)
.fontColor(this.validationResult.includes('✓') ? '#52c41a' : '#ff6b6b')
.margin({ bottom: 10 })
}
// 处理按钮
Button('处理')
.width('100%')
.height(40)
.margin({ bottom: 10 })
.onClick(() => {
this.processJson();
})
// 输出框
if (this.jsonOutput.length > 0) {
Column() {
Text('处理结果:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
TextArea()
.value(this.jsonOutput)
.enabled(false)
.height(150)
.padding(10)
.backgroundColor('#f5f5f5')
.border({ width: 1, color: '#cccccc' })
}
.width('100%')
.margin({ bottom: 15 })
}
// 分析结果
if (this.analysisResult.length > 0) {
Text(this.analysisResult)
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 15 })
}
// 查询功能
Column() {
Text('JSON 路径查询')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
Row() {
TextInput({ placeholder: '输入路径,如: name 或 items[0]' })
.value(this.queryPath)
.onChange((value: string) => {
this.queryPath = value;
})
.flex(1)
.padding(10)
.border({ width: 1, color: '#cccccc' })
Button('查询')
.width(60)
.height(40)
.margin({ left: 10 })
.onClick(() => {
this.queryJson();
})
}
.margin({ bottom: 10 })
if (this.queryResult.length > 0) {
Column() {
Text('查询结果:')
.fontSize(12)
.fontColor('#666666')
.margin({ bottom: 5 })
Text(this.queryResult)
.fontSize(12)
.selectable(true)
.padding(10)
.backgroundColor('#f5f5f5')
.borderRadius(4)
}
.width('100%')
}
}
.width('100%')
.padding(10)
.backgroundColor('#fafafa')
.borderRadius(4)
}
.padding(20)
.width('100%')
.height('100%')
.backgroundColor('#ffffff')
.scrollable(true)
}
}
ArkTS 代码说明: 这个示例展示了如何在 ArkTS 中构建一个完整的 JSON 处理用户界面。页面包含了模式选择、JSON 输入框、验证结果显示、处理按钮、输出框、分析结果和路径查询等组件。用户可以输入 JSON 数据,选择处理模式(格式化、压缩或分析),然后点击处理按钮查看结果。此外,页面还提供了路径查询功能,允许用户快速提取 JSON 中的特定值。
实战案例
案例 1: API 响应处理
在开发移动应用时,经常需要处理来自 API 的 JSON 响应。使用 JSON 工具可以快速验证响应的合法性,并提取所需的数据。
val tool = JsonFormatterValidator()
val apiResponse = """{"status":"success","data":{"userId":123,"userName":"John"}}"""
if (tool.isValidJson(apiResponse)) {
val userId = tool.getJsonValue(apiResponse, "data.userId")
val userName = tool.getJsonValue(apiResponse, "data.userName")
println("用户 ID: $userId, 用户名: $userName")
}
案例 2: 配置文件验证
在应用启动时,需要验证配置文件的合法性。使用 JSON 工具可以确保配置文件的格式正确。
val tool = JsonFormatterValidator()
val configJson = readConfigFile()
if (tool.isValidJson(configJson)) {
val analysis = tool.analyzeJson(configJson)
println("配置文件分析: $analysis")
} else {
println("配置文件格式错误,请检查")
}
案例 3: 日志数据分析
在分析日志数据时,经常需要处理 JSON 格式的日志。使用 JSON 工具可以快速格式化和分析日志数据。
val tool = JsonFormatterValidator()
val logJson = """{"timestamp":"2024-01-01T10:00:00","level":"INFO","message":"User login"}"""
val formatted = tool.formatJson(logJson)
println("格式化后的日志:\n$formatted")
val minified = tool.minifyJson(logJson)
println("压缩后的日志: $minified")
最佳实践
1. 验证优先
- 总是验证 JSON:在处理 JSON 前,先验证其合法性
- 提供错误信息:验证失败时提供详细的错误信息
- 处理异常:使用 try-catch 处理可能的异常
2. 性能优化
- 缓存验证结果:对于频繁使用的 JSON,缓存验证结果
- 流式处理:对于大型 JSON,使用流式处理而不是一次性加载
- 异步处理:对于耗时的 JSON 操作,使用异步处理
3. 安全考虑
- 防止注入攻击:验证 JSON 中的数据,防止恶意输入
- 限制递归深度:防止深层嵌套导致的栈溢出
- 验证数据类型:确保 JSON 中的数据类型符合预期
4. 用户体验
- 实时反馈:提供实时的验证和处理反馈
- 清晰的错误提示:错误发生时提供清晰的错误信息
- 支持多种操作:提供格式化、压缩、查询等多种操作
5. 可维护性
- 模块化设计:将不同的功能分解为独立的方法
- 充分的注释:为复杂的算法添加详细的注释
- 单元测试:编写单元测试确保功能的正确性
总结
JSON 格式化和验证工具是现代应用开发中的一个重要组件。通过使用 Kotlin Multiplatform,我们可以编写一次代码,然后在多个平台上运行,大大提高了开发效率和代码的可维护性。这个案例展示了如何实现 JSON 验证、格式化、压缩、查询和分析等功能。
在实际应用中,应该根据具体的需求选择合适的 JSON 处理方式,并遵循最佳实践来确保数据的准确性和安全性。同时,应该定期进行测试和优化,以提高应用的性能和用户体验。通过合理使用 JSON 工具,我们可以更加高效地处理和分析数据,提高应用的质量和可靠性。
更多推荐




所有评论(0)