Groovy - 处理 JSON 时的错误处理
错误处理是任何健壮应用程序的重要方面。Groovy 提供了 groovy.json.JsonException,专门用于处理使用 JsonSlurper 对象解析 JSON 字符串时可能发生的解析错误。除了解析错误外,我们还应该使用 Groovy 的标准 try-catch 功能来处理其他场景。以下是处理 JSON 时可能出现错误的常见用例及其对应的 Exception。
JsonException − 用于处理使用 JsonSlurper 解析 JSON 时的解析错误。
MissingPropertyException − 用于处理访问从 JSON 解析的对象中不存在的 key。
IndexOutOfBoundsException − 用于处理 JSON 数组中无效索引的情况。
NullPointerException − 用于处理访问 null 对象属性时的问题
NumberFormatException − 用于处理使用 JsonBuilder 转换值时的错误。
示例 - 处理 JSON 时的解析错误
使用 JsonSlurper 时,最佳实践是将 parseText 方法包装在 try-catch 块中以捕获 JsonException,如下例所示 −
Example.groovy
import groovy.json.JsonSlurper
import groovy.json.JsonException
def badJsonString = '''
{
"name": "Alice",
"age": 30,
"city": New York // 缺少引号
}
'''
def jsonSlurper = new JsonSlurper()
try {
def jsonData = jsonSlurper.parseText(badJsonString)
println jsonData
} catch (JsonException e) {
println "处理 JSON 时的解析错误: ${e.getMessage()}"
}
输出
运行上述程序时,将得到以下结果。
处理 JSON 时的解析错误: Unable to determine the current character, it is not a string, number, array, or object The current character read is 'N' with an int value of 78 Unable to determine the current character, it is not a string, number, array, or object line number 5 index number 45 "city": New York // Missing quotes ..........^
示例 - 创建 JSON 时的错误处理
使用 JsonBuilder 时,在编程处理数据过程中可能会遇到异常。建议使用 try-catch 捕获相关异常,如以下示例所示 −
Example.groovy
import groovy.json.JsonBuilder
def data = [name: "Charlie", age: "fortyfive"]
try {
def builder = new JsonBuilder()
builder {
name data.name
age data.age.toInteger() // toInteger 将抛出错误
}
println builder.toPrettyString()
} catch (NumberFormatException e) {
println "错误: 年龄不是有效数字 - ${e.getMessage()}"
}
输出
运行上述程序时,将得到以下结果。
错误: 年龄不是有效数字 - For input string: "fortyfive"
示例 - 解析 JSON 数据后处理错误
即使在解析 JSON 之后,处理各种场景也是一个好习惯,例如缺失属性、空对象访问、无效索引访问等,如以下示例所示 −
Example.groovy
import groovy.json.JsonSlurper
def jsonString = '''
{
"name": "A;ice",
"age": 25,
"hobbies": ["reading books","listening music"]
}
'''
def slurper = new JsonSlurper()
def person = slurper.parseText(jsonString)
try {
println "Name: ${person.name}"
println "City: ${person.city}"
// 如果 hobbies 不存在,会发生 MissingPropertyException
println "First hobby: ${person.hobbies[0]}"
// 如果索引越界,可能会发生 IndexOutOfBoundsException
println "Second hobby: ${person.hobbies[1]}"
// 如果 address 为 null,会发生 NullPointerException
println "Address zip: ${person.address.zip}"
} catch (MissingPropertyException e) {
println "Property missing - ${e.getProperty()}"
} catch (IndexOutOfBoundsException e) {
println "Invalid Index - ${e.getMessage()}"
} catch (NullPointerException e) {
println "Null Propery Accessed - ${e.getMessage()}"
}
输出
运行上述程序时,我们将得到以下结果。
Name: A;ice City: null First hobby: reading books Second hobby: listening music Null Propery Accessed - Cannot get property 'zip' on null object