当前位置: 首页 > 面试题库 >

Gson,JSON和LinkedTreeMap的精妙之处

韦衡
2023-03-14
问题内容

最近,我开始研究JSON字符串,并被告知Google自己的库Gson,是处理这些字符串的新方法。

据我了解,JSON字符串本质上是一个映射。每个变量指向字符串中的值的位置。

例如:

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\"}}";

我的问题是这些“括号内的括号”如何用于userJSON?” 部分?

我如何将这些内部括号中指定的值分配给变量?

谁能向我解释或向我展示代码,如何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格式。

基本上就是这样

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是一个对象external
{},它包含三对,created_at这是JSON字符串,id也是JSON字符串,并且user是JSON对象。该JSON对象包含另外三对都是JSON字符串。

你问

我如何将这些内部括号中指定的值分配给变量?

最高级的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]]

显示所有字段均已正确设置。

谁能向我解释,或向我展示代码,Gson如何处理此类事情以及如何使用?

Gson的源代码可免费获得。您可以在线找到它。这很复杂,源代码解释在这里不适合。简而言之,它使用Class您提供的对象来确定如何映射JSON对。它查看相应类的字段。如果这些字段是其他类,则它将重复进行,直到构造出需要反序列化的所有内容的映射为止。

简而言之,为什么…打印为空?

因为您的根JSON对象没有与name配对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类(这是父类的JsonObjectJsonArray和其他几个人)提供了一些方法来检查它是什么。参见javadoc。



 类似资料:
  • 问题内容: 使用来反序列化参数化类的对象会导致的某些值,例如对于由和字段组成的简单类型: 有趣的是,当内联调用方法时,相同的代码也可以工作,即以下语句返回有效值: 的定义也很简单: 将方法更改为非静态不能解决问题。 有任何想法吗? 问题答案: 您想要我的解决方案是ParameterizedType 问题是T,因为Java不知道我的种类并生成T的类型 这是测试更多示例以纠正运行测试 testCont

  • 问题内容: 我知道以前曾问过这个问题。由于我的Java和android新手技能。我不能解决这个问题超过一个星期。 我和我的一个朋友开发了一个android项目,那里有几件事。 这件事中最奇怪的部分是,它仅在我从Google Play商店下载并对其进行测试时才发生。不是从本地android studio安装或调试模式。 这可能是什么问题,或者此返回列表完全错误?我的朋友说服此代码可以正确返回,但是从

  • 最奇怪的是,只有当我从Google play商店下载并测试它时,它才会发生。不是从本地android studio安装或调试模式。 这里的问题是什么,或者这个返回列表是完全错误的?我的朋友确信,这段代码返回正确,但从play store安装,它总是一个错误。 请建议我在哪里继续挖掘? 例外是 java.lang.ClassCastException:com.google.gson.internal

  • 主要内容:概述,业务场景介绍,Spring Cloud核心组件:Eureka,Spring Cloud核心组件:Feign,Spring Cloud核心组件:Ribbon,Spring Cloud核心组件:Hystrix,Spring Cloud核心组件:Zuul,总结概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术。不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓。因此本文将通过大量的手绘图,

  • 我正在使用hibernate将对象映射到数据库。客户端(一个iOS应用程序)以JSON格式向我发送特定对象,我使用以下实用程序方法将其转换为真实的表示形式: 但问题是,在我的pogo中,我将值存储为一个byte[],如下所示(因为这是存储在数据库中的内容--一个blob): 当然,现在转换失败了,因为它不能在一个byte[]和一个字符串之间进行转换。 这里最好的方法是更改构造函数以接受字符串而不是