- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我最近开始研究 JSON
字符串,有人告诉我 Google 自己的库 Gson
是处理这些字符串的新潮方式。
我的理解是,JSON
字符串本质上是一张 map 。其中每个变量指向字符串中的一个值。
例如:
String jsonInput2 = "{\"created_at\":\"Sat Feb 08 15:37:37 +0000 2014\",\"id\":432176397474623489\"}
到目前为止,一切都很好。可以使用以下代码将诸如此 JSON
字符串创建时间之类的信息分配给变量:
Gson gson = new Gson();
Map<String, String> map = new HashMap<String, String>();
map = (Map<String, String>) gson.fromJson(jsonInput, map.getClass());
String createdAt = map.get("created_at");
它在简单的美中几乎是艺术的。但这就是美丽的终结和我的困惑开始的地方。
以下是上述JSON
字符串的扩展;
String jsonInput2 = "{\"created_at\":\"Sat Feb 08 15:37:37 +0000 2014\",\"id\":432176397474623489\",\"user\":{\"id_str\":\"366301747\",\"name\":\"somethingClever\",\"screen_name\":\"somethingCoolAndClever\"}}";
我的问题是这些“括号中的括号”如何用于 JSON
的 user
部分?
如何将这些内括号中指定的值分配给变量?
谁能给我解释一下,或者用代码告诉我,Gson
是如何处理这样的事情的,我该如何使用它?
简而言之,为什么...
String jsonInput = "{\"created_at\":\"Sat Feb 08 15:37:37 +0000 2014\",\"id\":432176397474623489\",\"user\":{\"id_str\":\"366301747\",\"name\":\"somethingClever\",\"screen_name\":\"somethingCoolAndClever\"}}";
Gson gson = new Gson();
Map<String, String> map = new HashMap<String, String>();
map = (Map<String, String>) gson.fromJson(jsonInput, map.getClass());
String name = map.get("name");
System.out.println(name);
...打印出null
?
最佳答案
忘记 Java。你需要先了解JSON format .
基本上就是这样
object
{}
{ members }
members
pair
pair , members
pair
string : value
array
[]
[ elements ]
elements
value
value , elements
value
string
number
object
array
true
false
null
您的第二个 JSON String
(缺少一个 "
)如下(使用 jsonlint.com 进行格式化)
{
"created_at": "Sat Feb 08 15:37:37 +0000 2014",
"id": "432176397474623489",
"user": {
"id_str": "366301747",
"name": "somethingClever",
"screen_name": "somethingCoolAndClever"
}
}
JSON 是一个对象,外部 {}
,包含三对,created_at
是一个 JSON 字符串,id
也是一个 JSON 字符串,user
是一个 JSON 对象。该 JSON 对象包含另外三对,它们都是 JSON 字符串。
你问
How could I assign the values specified within these inner-brackets to variables?
大多数高级 JSON 解析/生成库旨在将 JSON 转换为 Pojos 并返回。
因此您可以将 JSON 格式映射到 Java 类。
class Pojo {
@SerializedName("created_at")
private String createdAt;
private String id;
private User user;
}
class User {
@SerializedName("id_str")
private String idStr;
private String name;
@SerializedName("screen_name")
private String screenName;
}
// with appropriate getters, setters, and a toString() method
注意 @SerializedName
这样您就可以继续为您的字段使用 Java 命名约定。
您现在可以反序列化您的 JSON
Gson gson = new Gson();
Pojo pojo = gson.fromJson(jsonInput2, Pojo.class);
System.out.println(pojo);
会打印
Pojo [createdAt=Sat Feb 08 15:37:37 +0000 2014, id=432176397474623489", user=User [idStr=366301747, name=somethingClever, screenName=somethingCoolAndClever]]
显示所有字段都已正确设置。
Can anyone explain to me, or show me in code, how Gson handles stuff like this, and how I can use it?
Gson 的源代码是免费提供的。你可以在网上找到它。它很复杂,源代码解释不适合这里。简而言之,它使用您提供的 Class
对象来确定它将如何映射 JSON 对。它查看相应类的字段。如果这些字段是其他类,那么它会重复出现,直到它构建了一个包含所有需要反序列化的映射。
In short, why does...print out null?
因为您的根 JSON 对象没有一对名为 name
的对象。不使用 Map
,而是使用 Gson 的 JsonObject
类型。
JsonObject jsonObject = new Gson().fromJson(jsonInput2, JsonObject.class);
String name = jsonObject.get("user") // get the 'user' JsonElement
.getAsJsonObject() // get it as a JsonObject
.get("name") // get the nested 'name' JsonElement
.getAsString(); // get it as a String
System.out.println(name);
打印
somethingClever
如果类型不正确,上述方法类可能会抛出许多异常。例如,如果我们完成了
String name = jsonObject.get("user") // get the 'user' JsonElement
.getAsJsonArray() // get it as a JsonArray
它会失败,因为 user
不是 JSON 数组。具体来说,它会抛出
Exception in thread "main" java.lang.IllegalStateException: This is not a JSON Array.
at com.google.gson.JsonElement.getAsJsonArray(JsonElement.java:106)
at com.spring.Example.main(Example.java:19)
所以 JsonElement
类(它是 JsonObject
、JsonArray
和其他一些类的父类)提供了检查它是什么的方法。请参阅 javadoc。
关于java - Gson、JSON 和 LinkedTreeMap 的精妙之处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22285661/
我在序列化 JSON 数据时遇到问题。 所以,我尝试使用泛型,但不知何故,当我尝试实现它时,Gson 讨厌我。我想做的就是对泛型进行基本抽象。这是我的代码: 执行泛型部分的主类: package co
我只是想从我的 Gson 对象中获取值,所以在我的“城市”对象中: 我需要从“isSelected”中获取名称“first”和 bool 值。 我刚刚写了一个新类“KeyPairBoolData”:
我尝试在 Android 应用程序中使用 REST 服务,但在序列化 ArrayList 时遇到问题: 我的 RESTful 服务返回: 我的 Android 应用程序收到: 我正在使用 Gson 库
在标准 JDK 或支持排序和插入顺序的简单独立库中是否有可用的 LinkedTreeMap 实现?我找到了 gridsim有一个 LinkedTreeMap implementation .但它似乎是
我正在使用 Retrofit 2.0 从返回 json 文本的 Web 服务读取数据,但在以下代码中响应是 LinkedTreeMap,我无法将其转换为 json: 我的界面 public inter
我有一个如下所示的 JSON 结构: { "identifier": 1045608, "scientificName": "Apis mellifera Linnaeus 1758",
我正在尝试使我的响应类通用。问题是它返回一个 com.google.gson.internal.LinkedTreeMap 类型的列表,而不是 Brewer 类型。 启动这一切的函数: List br
我最近开始研究 JSON 字符串,有人告诉我 Google 自己的库 Gson 是处理这些字符串的新潮方式。 我的理解是,JSON 字符串本质上是一张 map 。其中每个变量指向字符串中的一个值。 例
对于 java 数据处理程序,我发送格式正确的 JSON,但 Spring、Java 决定如何转换它看到的内容以及框架的组合我真的不应该去改变破坏 JSON,以便一旦我能看到它,它变成了 Linked
我知道以前有人问过这个问题。由于我在java和android方面的新手技能。我无法解决这个问题超过一个星期。 我和我的一个 friend 正在开发一个 android 项目,如果有一些这样的事情。 这
我正在尝试通过 Retrofit 检索对象列表: public interface TemplateApi { @GET("/api/templates") Observable> g
这个问题已经有答案了: 奥 git _a (13 个回答) 已关闭 3 年前。 我在从 JSON 字符串获取对象时遇到一些问题。 我得到了 Product 类 public class Product
我第一次使用 GSON 进行改造。它在静态数据上运行流畅,但在动态数据的情况下显示上述错误。在设置文本值时在适配器中显示错误 主 Activity public class MainActivity
我正在尝试读取以下 json 数据。如何使用 LinkedTreeMap 进行阅读? {"msgType": "gameInit", "data": { "race": { "track"
下面这行代码对我来说很正常: val users: Array = com.google.gson.Gson().fromJson(data, Array::class.java) 但是当我启用 Pr
我是 kotlin 新手,刚刚将我的代码从 java 迁移到 kotlin。我有一个数据类 HistoryList,用于解析来自 API 的响应。 data class HistoryList(
我正在尝试通过广播在 Intent 中传递包含 Analytics Reporting 数据的对象。问题是反序列化返回 LinkedTreeMap 而不是原始序列化对象,导致 ClassCastExc
这个问题在这里已经有了答案: Gson TypeToken with dynamic ArrayList item type (13 个回答) 关闭3年前。 我在从 JSON 字符串中获取对象时遇到了
import com.google.gson.Gson import com.google.gson.reflect.TypeToken fun main() { val jsonString
我正在使用 Retrofit+Gson 来解析 JSON。 当我尝试解析来自 Google Places API 的响应时(好吧,我不尝试解析,我只是尝试为该响应创建模型),但出现了一些错误。 这是来
我是一名优秀的程序员,十分优秀!