
本教程详细介绍了如何在java/android环境中解析json数组(jsonarray),并根据特定键值(如电子邮件地址)筛选和提取所需数据,特别是经纬度信息。文章涵盖了json结构分析、迭代处理、数据提取、字符串清洗以及错误处理等关键步骤,旨在帮助开发者高效处理动态json数据。
理解JSON数组结构
在现代应用程序开发中,JSON(JavaScript Object Notation)已成为数据交换的标准格式。JSONArray代表一个有序的JSON值集合,通常包含多个JSONObject,每个JSONObject又是由键值对组成的无序集合。
以下是本文将处理的JSON数据示例,它是一个包含多个地理位置(lati和longt)及相关信息(如email)的数组:
[
{
"num": "34304",
"email": "[email protected]",
"lati": "8888888",
"longt": "88888888",
"time": "2022-12-08 21:15:39"
},
{
"num": "34303",
"email": "[email protected]",
"lati": "8888",
"longt": "88888",
"time": "8888888"
}
// ... 更多类似对象
]请注意,email字段的值是一个HTML字符串,其中包含一个标签,包裹着实际的电子邮件地址。在解析和筛选时,我们需要对这个HTML字符串进行处理以提取纯文本的电子邮件地址。
解析JSONArray并提取数据
解析JSONArray的基本步骤包括:将JSON字符串转换为JSONArray对象,然后遍历该数组,对每个JSONObject提取所需的数据。
立即学习“Java免费学习笔记(深入)”;
1. 将JSON字符串转换为JSONArray
首先,你需要将接收到的JSON字符串转换为org.json.JSONArray对象。
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
// 在Android项目中,你可能需要导入 android.text.Html
// import android.text.Html;
public class JsonDataProcessor {
public static void processJsonData(String jsonString, String targetEmail) {
List filteredLatLongs = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(jsonString);
// 遍历JSONArray
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
// 提取email字段,并进行HTML解码
String rawEmail = jsonObject.optString("email", "");
String cleanedEmail;
// 在Android环境中,使用Html.fromHtml进行解码
// cleanedEmail = Html.fromHtml(rawEmail).toString();
// 对于纯Java环境或简化示例,我们可以假设已经处理或直接使用
// 这里为了演示,我们手动从HTML字符串中提取可见的邮箱文本
if (rawEmail.contains("[email")) {
int startIndex = rawEmail.indexOf(">");
int endIndex = rawEmail.indexOf("");
if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
cleanedEmail = rawEmail.substring(startIndex + 1, endIndex);
} else {
cleanedEmail = rawEmail; // 如果格式不符,则使用原始字符串
}
} else {
cleanedEmail = rawEmail; // 如果不是HTML格式,直接使用
}
// 根据电子邮件地址进行筛选
if (targetEmail.equals(cleanedEmail)) {
String lati = jsonObject.getString("lati");
String longt = jsonObject.getString("longt");
filteredLatLongs.add("Lati: " + lati + ", Longt: " + longt);
}
}
// 输出筛选结果
System.out.println("针对邮箱 " + targetEmail + " 的筛选结果:");
if (filteredLatLongs.isEmpty()) {
System.out.println("未找到匹配的条目。");
} else {
for (String latLong : filteredLatLongs) {
System.out.println(latLong);
}
}
} catch (JSONException e) {
System.err.println("解析JSON时发生错误: " + e.getMessage());
} catch (NumberFormatException e) {
System.err.println("将经纬度字符串转换为数字时发生错误: " + e.getMessage());
}
}
public static void main(String[] args) {
String sampleJson = "[{\"num\": \"34304\",\"email\": \"[email protected]\",\"lati\": \"8888888\",\"longt\": \"88888888\",\"time\": \"2022-12-08 21:15:39\"},{\"num\": \"34303\",\"email\": \"[email protected]\",\"lati\": \"8888\",\"longt\": \"88888\",\"time\": \"8888888\"},{\"num\": \"34302\",\"email\": \"[email protected]\",\"lati\": \"8888\",\"longt\": \"88888\",\"time\": \"8888888\"},{\"num\": \"34301\",\"email\": \"[email protected]\",\"lati\": \"8888\",\"longt\": \"88888\",\"time\": \"8888888\"},{\"num\": \"34300\",\"email\": \"[email protected]\",\"lati\": \"8888\",\"longt\": \"88888\",\"time\": \"8888888\"}]";
String targetEmailToFilter = "[email protected]"; // 要筛选的邮箱
processJsonData(sampleJson, targetEmailToFilter);
}
} 2. 代码解释
- JSONArray jsonArray = new JSONArray(jsonString);: 这一行将原始的JSON字符串解析成一个JSONArray对象。
- for (int i = 0; i : 遍历JSONArray中的每一个元素。
- JSONObject jsonObject = jsonArray.getJSONObject(i);: 在每次迭代中,获取当前索引位置的JSONObject。
- String rawEmail = jsonObject.optString("email", "");: 使用optString方法安全地获取email字段的值。optString在键不存在时会返回默认值(这里是空字符串),而不是抛出JSONException。
-
HTML解码处理:
- 在Android开发中,推荐使用android.text.Html.fromHtml(rawEmail).toString()来解析HTML字符串,获取纯文本内容。
- 在纯Java环境中,如果没有引入额外的HTML解析库(如Jsoup),你可以通过字符串操作(如substring配合indexOf和lastIndexOf)来提取标签内的文本。示例代码中提供了一个简单的字符串截取逻辑。
- if (targetEmail.equals(cleanedEmail)) { ... }: 这是一个条件判断,用于检查当前对象的cleanedEmail是否与我们想要筛选的目标邮箱匹配。
- String lati = jsonObject.getString("lati"); 和 String longt = jsonObject.getString("longt");: 如果邮箱匹配成功,则提取lati和longt字段的值。getString方法在键不存在时会抛出JSONException,因此通常建议在确定键一定存在时使用,或者配合optString进行更安全的访问。
- 错误处理: 使用try-catch块捕获JSONException(JSON解析错误)和NumberFormatException(如果尝试将非数字字符串转换为数字)。
注意事项与最佳实践
- 异常处理: 始终使用try-catch块来处理JSONException,因为JSON解析过程中可能会出现格式错误。
-
安全获取值:
- 使用optString(key, defaultValue)、optInt(key, defaultValue)等opt系列方法,可以在键不存在时返回一个默认值,而不是抛出异常,这使得代码更健壮。
- 如果你确定某个键一定存在且其值类型已知,可以使用getString(key)、getInt(key)等方法,它们会在键不存在或类型不匹配时抛出JSONException。
- HTML内容处理: 如果JSON中的字符串包含HTML标签(如示例中的email字段),在Android中使用Html.fromHtml()是提取纯文本的常用且有效的方法。对于更复杂的HTML解析需求,可以考虑引入第三方库如Jsoup。
- 数据类型转换: 经纬度通常是浮点数。在提取字符串后,如果需要进行数值计算,记得将其转换为double类型,例如Double.parseDouble(lati)。
- 性能: 对于非常大的JSONArray,频繁的字符串操作和对象创建可能会影响性能。在处理海量数据时,考虑优化数据结构或使用流式解析。
- 目标邮箱匹配: 示例中的[email protected]实际上是Cloudflare的邮件保护机制。Html.fromHtml()会将其解析为可见的文本。如果实际需要匹配的是原始的、未










