JSON基础知识

目录

  • 一、定义
  • 二、作用
  • 三、特点
  • 四、语法
    • JSON具有以下这些形式:
      • 4.1 对象(JSONObject):
      • 4.2 数组(JSONArray):
      • 4.3 值
      • 4.4 字符串
      • 4.5 数值
  • 五、常用的JSON解析方式
    • 5.1 org.json解析
      • 5.1.1 常用api
      • 5.1.2 get方法与opt方法对比
      • 5.1.3 使用示例
      • 5.1.3 参考链接
    • 5.2 Gson 解析
      • 5.2.1 特点
      • 5.2.2 常用api
      • 5.2.3 常用注解
      • 5.2.4 序列化/反序列化接口
      • 5.2.5 使用示例
      • 5.2.6 参考链接
    • 5.3 Jackson解析
      • 5.3.1 核心组件
      • 5.3.2 注解
      • 5.3.3 使用示例
      • 5.3.4 参考链接
    • 5.4 Fastjson解析
      • 5.4.1 特点
      • 5.4.2 常用API
      • 5.4.3 使用示例
      • 5.4.4 参考链接


一、定义

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式


二、作用

数据标记,存储,传输

三、特点

  1. 读写速度快
  2. 解析简单
  3. 轻量级
  4. 独立于语言,平台
  5. 具有自我描叙性

四、语法

JSON建构于两种结构:

  • “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组(associative array)。
  • 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
    这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

JSON具有以下这些形式:

4.1 对象(JSONObject):

对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
在这里插入图片描述

4.2 数组(JSONArray):

数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
在这里插入图片描述

4.3 值

值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。
在这里插入图片描述

{
"url": "https://qqe2.com",
"name": "欢迎使用JSON在线解析编辑器",
"array": {
"JSON校验": "http://jsonlint.qqe2.com/",
"Cron生成": "http://cron.qqe2.com/",
"JS加密解密": "http://edit.qqe2.com/"
},
"boolean": true,
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d",
"e": "f"
	}
}

4.4 字符串

字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。字符串(string)与C或者Java的字符串非常相似。
在这里插入图片描述

{
"name": "Zero",
}

4.5 数值

数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。
在这里插入图片描述

{
"age": 28,
}

五、常用的JSON解析方式

5.1 org.json解析

org.json 是 Android 平台中用于处理 JSON 数据的一个标准库。该库提供了一组类,使开发人员能够轻松地解析和构建 JSON 数据。

5.1.1 常用api

JSONObject 类:JSONObject 类表示一个 JSON 对象,可以包含键值对。通过 JSONObject 类,您可以将 JSON 字符串解析为对象,或者将对象转换为 JSON 字符串。
JSONObject.put(String key, Object value):将指定的键值对添加到 JSON 对象中。
JSONObject.get(String key):获取指定键对应的值。
JSONObject.has(String key):检查 JSON 对象中是否包含指定的键。
JSONObject.toString():将 JSON 对象转换为字符串表示形式。
JSONObject.keys():获取 JSON 对象中所有的键。
JSONArray 类:JSONArray 类表示一个 JSON 数组,可以包含多个元素。通过 JSONArray 类,您可以处理包含多个数据项的 JSON 数组。
JSONArray.put(Object value):向 JSON 数组中添加一个元素。
JSONArray.get(int index):获取指定索引位置的元素。
JSONArray.length():获取 JSON 数组的长度。
JSONArray.toString():将 JSON 数组转换为字符串表示形式。
JSONArray.toList():将 JSON 数组转换为 Java List 对象。
JSONException 类:JSONException 是 org.json 库中定义的异常类,用于处理 JSON 解析和构建过程中的异常情况。
JSONException(String message):使用指定的详细消息构造一个新的异常实例。
JSONException(Throwable cause):使用指定的原因构造一个新的异常实例。

5.1.2 get方法与opt方法对比

opt 相关的 API提供了更安全的方式来获取 JSON 对象中的值,可以处理缺失键或空值的情况,而 get 相关的 API则更适用于确保键存在且值不为 null 的情况下获取值,但在键不存在或值为 null 时会引发异常。

opt 相关的 API
opt 相关的方法(如 optString(String key) 和 optInt(String key))是安全的方法,用于从 JSON 对象中获取特定键对应的值。
如果指定键不存在或值为 null,opt 方法会返回一个默认值(如空字符串 " " 或 0)而不会抛出异常。
这些方法适用于处理可能存在缺失键或空值的情况,可以避免空指针异常。
get 相关的 API
get 相关的方法(如 getString(String key) 和 getInt(String key))用于从 JSON 对象中获取特定键对应的值,但如果键不存在或值为 null,会抛出异常(如 JSONException)。
这些方法适用于确保 JSON 对象中包含指定键,并且值不为 null 的情况下获取值。

5.1.3 使用示例

void test() {
        try {
            // 构建一个 JSON 对象
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("name", "Alice");
            jsonObject.put("age", 25);
            Log.d("henry", "" + jsonObject);

            // 构建一个 JSON 数组
            JSONArray jsonArray = new JSONArray();
            jsonArray.put("apple");
            jsonArray.put("banana");
            jsonArray.put("cherry");
            Log.d("henry", "" + jsonArray);

            // 将 JSON 对象和 JSON 数组组合成一个新的 JSON 对象
            JSONObject mainObject = new JSONObject();
            mainObject.put("person", jsonObject);
            mainObject.put("fruits", jsonArray);
            Log.d("henry", "" + mainObject);

            // 将 JSON 对象转换为字符串输出
            String jsonString = mainObject.toString();
            Log.d("henry", "" + jsonString);

            // 解析 JSON 字符串
            JSONObject parsedObject = new JSONObject(jsonString);
            Log.d("henry", "" + parsedObject.get("person"));

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

输出:
在这里插入图片描述

5.1.3 参考链接

Android-封装JSON数据(JSON对象/JSON数组)
Android中JSON使用总结

5.2 Gson 解析

Gson 是 Google 提供的一个用于在 Java 对象和 JSON 数据之间进行序列化和反序列化的库。它可以帮助开发人员轻松地将 Java 对象转换为 JSON 格式的数据,也可以将 JSON 数据转换为 Java 对象。

5.2.1 特点

  • 简单易用:Gson 提供了简单的 API,使得序列化和反序列化操作变得非常容易。
  • 灵活性:Gson 支持处理复杂的 Java 对象结构,包括嵌套对象、集合、数组等。
  • 自定义性:可以通过自定义序列化器和反序列化器来控制 Gson 的行为,以满足特定需求。
  • 高性能:Gson 在序列化和反序列化过程中具有较高的性能,能够有效地处理大量数据

5.2.2 常用api

Gson gson = new Gson():  创建一个 Gson 实例,用于进行序列化和反序列化操作。
GsonBuilder:   Gson 提供了 GsonBuilder 类来配置 Gson 的行为,例如设置日期格式、处理 null 值等。
示例:Gson gson = new GsonBuilder().setDateFormat(“yyyy-MM-dd”).create();
toJson(Object src):   将 Java 对象转换为 JSON 格式的字符串。
toJson(Object src, Type typeOfSrc):  将 Java 对象转换为 JSON 格式的字符串,支持泛型类型。
toJsonTree(Object src):   将 Java 对象转换为 Gson 的 JsonElement 对象,可以进一步处理该对象。
toJson(Object src, Appendable writer):   将 Java 对象转换为 JSON 格式并写入到指定的 Appendable 对象中,如 FileWriter、StringWriter 等。

fromJson(String json, Class< T> classOfT):  将 JSON 字符串转换为指定类型的 Java 对象。
fromJson(String json, Type typeOfT):   将 JSON 字符串转换为指定泛型类型的 Java 对象。
fromJson(JsonElement json, Class< T> classOfT):  将 JsonElement 对象转换为指定类型的 Java 对象。
fromJson(Reader json, Class<T> classOfT):  从 Reader 对象中读取 JSON 数据并将其转换为指定类型的 Java 对象。

5.2.3 常用注解

  • @Expose 该注解用于指定字段是否参与序列化和反序列化。
    其中,serialize 参数用于指定字段是否参与序列化,deserialize 参数用于指定字段是否参与反序列化。
  • @Since 该注解表示字段在指定版本之后才会参与序列化和反序列化。
  • @Until 该注解表示字段在指定版本之前才会参与序列化和反序列化。
  • @JsonAdapter 该注解指定了使用自定义的 JsonAdapter(JSON 适配器)来序列化和反序列化该字段。

示例

//当将该注解应用于字段时,表示该字段不会参与序列化,
//即在将 Java 对象转换为 JSON 字符串时,该字段不会包含在生成的 JSON 数据中
@Expose(serialize = false)
private String sensitiveData;

//当将该注解应用于字段时,表示该字段不会参与序列化,但会参与反序列化,
//即在将 JSON 数据转换为 Java 对象时,可以从 JSON 数据中读取该字段的值。
@Expose(serialize = false, deserialize = true)
private int readOnlyField;

//在将 Java 对象转换为 JSON 字符串时,只有在指定版本号(1.0)之后才会包含该字段;
//反之,从 JSON 数据转换为 Java 对象时,只有在指定版本号之后的 JSON 数据才会包含该字段。
@Since(1.0)
private String newField;

//该注解表示字段在指定版本之前才会参与序列化和反序列化。在将 Java 对象转换为 JSON 字符串时,只有在指定版本号(1.1)之前才会包含该字段;
//反之,从 JSON 数据转换为 Java 对象时,只有在指定版本号之前的 JSON 数据才会包含该字段。
@Until(1.1)
private String legacyField;

//该注解指定了使用自定义的 JsonAdapter(JSON 适配器)来序列化和反序列化该字段。
//通过自定义的 JsonAdapter,可以实现对字段的定制化处理,例如特定格式的日期转换、自定义逻辑等。
@JsonAdapter(UserJsonAdapter.class)
private CustomObject customField;

5.2.4 序列化/反序列化接口

在 Gson 库中,有两个重要的接口用于自定义 JSON 数据的序列化和反序列化过程:JsonSerializer 和 JsonDeserializer。

JsonSerializer 接口JsonDeserializer 接口
作用通过实现 JsonSerializer 接口并重写 serialize 方法,可以指定如何将 Java 对象转换为符合要求的 JSON 格式的数据。通过实现 JsonDeserializer 接口并重写 deserialize 方法,可以指定如何将 JSON 数据转换为 Java 对象。
接口JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context);T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException;

简单示例:

public class GsonError1 {

    /**
     * name : java
     * authors :
     */
    private String name;
    private List<AuthorsBean> authors;

    @Override
    public String toString() {
        return "GsonError1{" +
                "name='" + name + '\'' +
                ", authors=" + authors +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<AuthorsBean> getAuthors() {
        return authors;
    }

    public void setAuthors(List<AuthorsBean> authors) {
        this.authors = authors;
    }

    public static class AuthorsBean {
        /**
         * id : 1'
         * name : Joshua Bloch'
         */

        private String id;
        private String name;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "AuthorsBean{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    static class GsonError1Deserializer implements JsonDeserializer<GsonError1> {

        @Override
        public GsonError1 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            final JsonObject jsonObject = json.getAsJsonObject();
            final JsonElement jsonTitle = jsonObject.get("name");
            final String name = jsonTitle.getAsString();

            JsonElement jsonAuthors = jsonObject.get("authors");

            GsonError1 gsonError1 = new GsonError1();

            if (jsonAuthors.isJsonArray()) {//如果数组类型,此种情况是我们需要的
                //关于context在文章最后有简单说明
                AuthorsBean[] authors = context.deserialize(jsonAuthors, AuthorsBean[].class);
                gsonError1.setAuthors(Arrays.asList(authors));
            } else {//此种情况为无效情况
                gsonError1.setAuthors(null);
            }
            gsonError1.setName(name);
            return gsonError1;
        }
    }
        public static void test3() {
        //TODO:
        String json = "{\n" +
                "    \"name\": \"java\",\n" +
                "    \"authors\": \"\"\n" +
                "}";

        GsonBuilder gsonBuilder = new GsonBuilder();

        //注册TypeAdapter
        gsonBuilder.registerTypeAdapter(GsonError1.class, new GsonError1Deserializer());
        
        Gson gson = gsonBuilder.create();
        GsonError1 gsonError1 = gson.fromJson(json, GsonError1.class);
        System.out.println(gsonError1);
    }
    
    public static void main(String... args) {
        test3();
    }
}

输出:
在这里插入图片描述

5.2.5 使用示例

导入依赖

    implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
public class Response<T> {
    public Response(T data, int code, String message) {
        this.data = data;
        this.code = code;
        this.message = message;
    }

    T data;
    int code;
    String message;

    @NonNull
    @Override
    public String toString() {
        return "Response{" +
                "data=" + data +
                ",  code=" + code +
                ", message=' " + message + '\'' +
                '}';
    }

    static class Data {
        public Data(String result) {
            this.result = result;
        }

        String result;

        @Override
        public String toString() {
            return "Data{" +
                    "result='" + result + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) {
        GsonBean();
        GsonList();
        GsonMap();
    }


    /**
     * 先创建Person对象。
     * 在创建Gson对象。
     * 调用Gson的String toJson(Object)方法,来将对象转换为json字符串。
     * 调用Gson的T fromJson()方法,来将json字符串转换为对象。
     */
    static void GsonBean() {
        Response<Data> dataResponse = new Response<>(new Data("Bean数据"), 1, "成功");
        Gson gson = new Gson();
        String json = gson.toJson(dataResponse);
        System.out.println("Bean数据 json字符串 =" + json);
        //来将对象转换为json字符串
        Response<Data> resp = gson.fromJson(json, new TypeToken<Response<Data>>() {
        }.getType());
        System.out.println("Bean数据捕获 data =" + resp);
        // 调用Gson的 <T> t fromJson(String, Class)方法,将Json串转换为对象
        Response resp2 = gson.fromJson(json, Response.class);
        System.out.println("Bean数据 =" + resp2);
        System.out.println("-----------------");
    }

    //为什么TypeToken要定义为抽象类?

    /**
     * 在进行GSON反序列化时,存在泛型时,可以借助 TypeToken 获取Type以完成泛型的反序列化。但是为什么TypeToken 要被定义为抽象类呢?
     * 因为只有定义为抽象类或者接口,这样在使用时,需要创建对应的实现类,此时确定泛型类型,编译才能够将泛型signature信息记录到Class元数据中。
     */
    public static void GsonList() {
        // 先准备一个List集合
        List<Response> list = new ArrayList<Response>();
        list.add(new Response(new Data("List数据1"), 10, "成功"));
        list.add(new Response(new Data("List数据2"), 20, "成功"));
        // 创建Gson实例
        Gson gson = new Gson();
        // 调用Gson的toJson方法
        String listJson = gson.toJson(list);
        System.out.println("list数据 json字符串 =" + listJson);
        // 如果还调用 <T> t fromJson(String, Class)方法,那么返回的虽然还是个List集合,但是集合里面的数据却不是Person对象,而是Map对象
        List fromJson = gson.fromJson(listJson, List.class);
        System.out.println("list数据 fromJson 集合数据类型 =" + fromJson.get(0).getClass());
        // class com.google.gson.internal.LinkedTreeMap
        //要想获取的List还和之前的一毛一样,通过Gson包提供的TypeToken获取
        // 调用Gson的 T fromJson(String, Type)将List集合的json串反序列化为List对象
        List<Response> plist = gson.fromJson(listJson, new TypeToken<List<Response>>() {
        }.getType());
        System.out.println("list数据 fromJson TypeToken =" + plist);
        System.out.println("-----------------");
    }

    /**
     * 转换Map的步骤和转换List的步骤一模一样
     */
    public static void GsonMap() {

        Map<String, Response> map = new HashMap<>();
        map.put("p1", new Response(new Data("Map数据1"), 10, "成功"));
        map.put("p2", new Response(new Data("Map数据2"), 20, "成功"));

        Gson gson = new Gson();
        String mapJson = gson.toJson(map);

        System.out.println("Map数据 json字符串 =" + mapJson);
        Map<String, Response> jsonMap = gson.fromJson(mapJson, new TypeToken<Map<String, Response>>() {
        }.getType());
        System.out.println("Map数据 fromJson TypeToken =" + jsonMap);
    }

}

输出:
在这里插入图片描述

5.2.6 参考链接

采用Gson解析含有多种JsonObject的复杂json
Gson的基本使用

5.3 Jackson解析

Jackson 是一个用于处理 JSON 数据的流行 Java 库,它提供了强大且灵活的 API,用于序列化和反序列化 Java 对象与 JSON 数据之间的转换。

5.3.1 核心组件

ObjectMapper:ObjectMapper 是 Jackson 库中最重要的类之一,用于执行 Java 对象与 JSON 数据之间的转换。它提供了一系列方法,如 writeValueAsString(将 Java 对象转换为 JSON 字符串)、readValue(将 JSON 字符串转换为 Java 对象)等。

JsonNode:JsonNode 是 Jackson 中表示 JSON 数据的树形结构的抽象类。它可以表示 JSON 对象、JSON 数组、JSON 字符串等,提供了方便的方法来访问和操作 JSON 数据。

JsonParser 和 JsonGenerator:JsonParser 用于解析 JSON 数据流,而 JsonGenerator 用于生成 JSON 数据流。它们提供了对 JSON 数据的逐个元素访问和生成的功能。

5.3.2 注解

Jackson 提供了一系列注解,用于控制序列化和反序列化过程:

@JsonSerialize 和 @JsonDeserialize:用于指定自定义的序列化和反序列化类。
@JsonProperty:用于指定 Java 对象属性与 JSON 数据字段的映射关系。
@JsonIgnore:用于忽略特定属性的序列化和反序列化。
等等。

5.3.3 使用示例

导入依赖:

    implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
    implementation 'com.fasterxml.jackson.core:jackson-core:2.9.8'
    implementation 'com.fasterxml.jackson.core:jackson-annotations:2.9.8'
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        testJackson();
    }
    public static class User {
        private String name;
        private int age;

        public User() {
        }

        public User(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setAge(int age) {
            this.age = age;
        }


        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

    }

    public static void testJackson() {
        try {
            // 创建 ObjectMapper 对象
            ObjectMapper objectMapper = new ObjectMapper();

            // 创建一个 User 对象
            User user = new User("Bob", 30);

            // 将 User 对象转换为 JSON 字符串
            String json = objectMapper.writeValueAsString(user);
            Log.d("JacksonTest", "Serialized JSON: " + json);

            // 将 JSON 字符串转换为 User 对象
            User deserializedUser = objectMapper.readValue(json, User.class);
            Log.d("JacksonTest", "Deserialized User: " + deserializedUser.getName() + ", " + deserializedUser.getAge());
        } catch (Exception e) {
            Log.e("JacksonTest", "Error during Jackson test: " + e.getMessage());
        }
    }

输出:
在这里插入图片描述

5.3.4 参考链接

Jackson使用详解

5.4 Fastjson解析

Fastjson 是阿里巴巴开源的 JSON 解析库,具有高性能和丰富的功能。

5.4.1 特点

高性能:Fastjson 在 JSON 解析和生成方面具有优秀的性能,速度快,效率高,被广泛应用于各种场景。
功能丰富:Fastjson 提供了丰富的功能,支持将 Java 对象序列化为 JSON 字符串,以及将 JSON 字符串反序列化为 Java 对象。同时支持复杂数据结构(如嵌套对象、集合等)的序列化和反序列化。
灵活性:Fastjson 提供了多种配置选项和定制功能,可以根据需求进行灵活设置,以满足不同的应用场景。
广泛应用:Fastjson 在阿里巴巴集团内部被大量使用,也被广泛应用于其他公司和开发者的项目中,是业界常用的 JSON 解析库之一。
开源免费:Fastjson 是开源项目,采用 Apache License 2.0 开源协议,可以免费使用和修改,适合于商业和个人项目。
持续更新:Fastjson 持续得到维护和更新,不断优化性能和功能,保持与最新的 JSON 标准兼容。

5.4.2 常用API

  • 序列化(将 Java 对象转换为 JSON 字符串):
    JSON.toJSONString(Object object): 将 Java 对象序列化为 JSON 字符串。
    JSON.toJSONString(Object object, SerializerFeature… features): 可以传入序列化配置参数,如日期格式化、空值处理等。
  • 反序列化(将 JSON 字符串转换为 Java 对象):
    JSON.parseObject(String text, Class clazz): 将 JSON 字符串反序列化为指定类型的 Java 对象。
    JSON.parseObject(String text, Type type): 将 JSON 字符串反序列化为指定类型的 Java 对象,支持复杂泛型类型。
  • 序列化和反序列化配置:
    SerializerFeature: 序列化配置项,可用于设置日期格式、空值处理、循环引用处理等。
    ParserConfig: 反序列化配置,可用于设置反序列化时的特殊处理。
  • 其他常用方法:
    JSONObject: Fastjson 中的 JSON 对象,可以用于创建和操作 JSON 数据。
    JSONArray: Fastjson 中的 JSON 数组,可以用于创建和操作 JSON 数据。
    JSON.isValid(String text): 判断一个字符串是否为有效的 JSON 格式。
    JSON.parseArray(String text): 将 JSON 数组字符串解析为 Java List 对象。

5.4.3 使用示例

导入依赖

    implementation 'com.alibaba:fastjson:1.2.78'
public class FastJsonTest {

    public static class User {

        private Long id;
        private String name;

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    public static class Group {
        public Group() {
        }

        private Long id;
        private String name;
        private List<User> users = new ArrayList<User>();

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<User> getUsers() {
            return users;
        }

        public void setUsers(List<User> users) {
            this.users = users;
        }

        public void addUser(User user) {
            users.add(user);
        }

        @Override
        public String toString() {
            return "Group{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", users=" + users +
                    '}';
        }
    }

    public static void main(String[] args) {
        //序列化
        Group group = new Group();
        group.setId(0L);
        group.setName("admin");

        User guestUser = new User();
        guestUser.setId(2L);
        guestUser.setName("guest");

        User rootUser = new User();
        rootUser.setId(3L);
        rootUser.setName("root");

        group.addUser(guestUser);
        group.addUser(rootUser);

        String jsonString = JSON.toJSONString(group);
        System.out.println(jsonString);

        //反序列化
        //"{}"表示对象,"[]"表示对象数组(List),一定要有getter和setter。
        String jsonString1 = "{\"id\":0,\"name\":\"admin\",\"users\":[{\"id\":2,\"name\":\"guest\"},{\"id\":3,\"name\":\"root\"}]}";
        Group group1 = JSON.parseObject(jsonString1, Group.class);
        System.out.println(group1.getUsers().get(0).toString());
        System.out.println(group1.toString());

        //处理时间
        Date date = new Date(System.currentTimeMillis());
        System.out.println(JSON.toJSONStringWithDateFormat(date, "yyyy-MM-dd HH:mm:ss.SSS"));
        System.out.println(JSON.toJSONString(date, SerializerFeature.UseISO8601DateFormat));
        JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";
        System.out.println(JSON.toJSONString(date, SerializerFeature.WriteDateUseDateFormat));
    }

}

输出:
在这里插入图片描述

5.4.4 参考链接

Alibaba Fastjson——超好用的JOSN解析库
经过多方调研,最终还是决定禁用FastJson 这篇很有趣,哈哈哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/450950.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面试不再愁,看这份保姆级简历写作指南

在现代社会&#xff0c;简历是求职过程中至关重要的一环。一份精心设计的简历可以为你打开求职的大门&#xff0c;让你脱颖而出。然而&#xff0c;许多求职者常常陷入简历写作的困境&#xff0c;不知道从何处入手。在这篇文章中&#xff0c;我将手把手地教你如何写一份引人注目…

Jmeter接口自动化-如何解决请求头Content-Type冲突问题

一、前言 通常我们在使用Jmeter做接口自动化时&#xff0c;在线程组里添加HTTP信息头管理器&#xff0c;用来管理公共的请求头信息。普通的接口自动化是没问题的&#xff0c;但是对于有些特殊的操作流程&#xff0c;如&#xff1a;先上传文件接口&#xff08;信息头使用Conten…

openGauss学习笔记-240 openGauss性能调优-SQL调优-更新统计信息

文章目录 openGauss学习笔记-240 openGauss性能调优-SQL调优-更新统计信息240.1 背景信息240.2 操作步骤 openGauss学习笔记-240 openGauss性能调优-SQL调优-更新统计信息 在数据库中&#xff0c;统计信息是规划器生成计划的源数据。没有收集统计信息或者统计信息陈旧往往会造…

01 THU大模型之基础入门

1. NLP Basics Distributed Word Representation词表示 Word representation: a process that transform the symbols to the machine understandable meanings 1.1 How to represent the meaning so that the machine can understand Compute word similarity 计算词相似度 …

Huggingface中Transformer模型使用

一、Huggingface介绍 1、Huggingface定位 NLP自从Transformer模型出现后&#xff0c;处理方式有大统一的趋势&#xff0c;首先回答几个基础问题&#xff1a; 1、自然语言处理究竟要做一件什么事呢&#xff1f;自然语言处理最终解决的是分类问题&#xff0c;但是它不仅仅输出…

算法之二分查找算法

二分查找算法简介 1. 首先说明二分查找算法是比较恶心, 细节很多, 很容易写出死循环的算法, 但熟悉了之后是最简单的算法. 2. 其次我们可能听说过二分查找的前提是数组有序的前提下进行, 但其实不一定. 3. 二分查找算法有一套模板: 朴素的二分模板: 比较简单, 但是有局限性查找…

运维自动化之ansible

pxe 一键安装操作系统 操作系统只是提供一个平台 lnmp 需要多软件协同完成的一个简单项目 服务器正常运行 日常运维 巡检 服务器上的软件正常运行 zabbix 普罗米修斯 系统调优&#xff0c;架构调优 云计算核心职能 搭建平台架构 日常运营保障 性能效率优化 相关工具 代…

SDWAN专线对企业接入有门槛吗

SD-WAN&#xff08;软件定义广域网&#xff09;技术作为一种新型的网络解决方案&#xff0c;正在成为企业网络接入的热门选择。然而&#xff0c;对于企业来说&#xff0c;接入SD-WAN专线是否存在门槛&#xff0c;是一个值得探讨的问题。本文将从不同角度分析SD-WAN专线对企业接…

HTML 学习笔记(十一)表单

一、分块 1.单行文本框控件–文本框和密码框 文本框控件通过单标签input实现&#xff0c;其具有必要属性type来控制输入控件的类型(默认为text即文本信息)&#xff0c;密码框的type为password(口令)。   表单的动作属性定义了目的文件的文件名。由动作属性定义的这个文件通常…

国内可用免费AI工具集

1、Kimi Chat 由月之暗面科技有限公司&#xff08;Moonshot AI&#xff09;开发的人工智能助手。擅长中英文对话&#xff0c;能够提供安全、有帮助且准确的回答。它的能力包括阅读和理解用户上传的文件&#xff0c;访问互联网内容&#xff0c;以及结合搜索结果来回答问题。比如…

【C#】WPF获取屏幕分辨率

SystemParameters提供的接口&#xff0c;其实是获取渲染过程中的实际高宽&#xff0c;是受系统DPI设置的影响。 以 1920 * 1080 和 125% DPI为例&#xff1a; 分辨率高度&#xff1a;1080&#xff0c;实际获取的高度为&#xff1a;864。 分辨率宽度&#xff1a;1920&#xff…

高项-项目整合管理

项目整合管理的目标 资源分配平衡竞争性需求研究各种备选方法裁剪过程以实现项目目标管理各个项目管理知识域之间的依赖关系 项目整合管理的过程 制定项目章程制定项目管理计划指导与管理项目工作管理项目知识监控项目工作实施整体变更控制结束项目或阶段 七个过程和五大过…

【1688运营】如何拆解竞争对手店铺和单品数据?

关注竞争对手数据是1688运营中不可或缺的一环&#xff0c;它有助于企业更好地了解市场环境、发现市场机会、学习成功经验、预测市场变化以及提升竞争力。以下是一些建议&#xff0c;帮助你全面、深入地分析竞争对手的店铺和单品数据&#xff1a; 1、监控店铺数据 可以通过店雷…

求第n个斐波那契数--c语言

用递归的方法&#xff1a; //用递归求第n个斐波那契数 int fib(int n){if(n<2){return 1;}else{return fib(n-1)fib(n-2); } } #include<stdio.h> int main(){int n0;printf("请输入n的值&#xff1a;");scanf("%d",&n);int result fib(n);…

未来艺术展览新趋势——3D线上画展如何创新展示?

一、艺术展示的数字化转型 随着科技的不断进步&#xff0c;3D线上画展作为艺术展示的新趋势&#xff0c;正逐渐改变着人们欣赏和购买艺术作品的方式。对于画家而言&#xff0c;3D线上画展不仅提供了一个全新的平台来展示他们的作品&#xff0c;还开辟了销售渠道&#xff0c;扩大…

面向对象技术(第一周)

目录 ⚽前言 &#x1f3d0;面向对象思想 起源 现实 编程联系 面向对象思想总结 &#x1f3c0;面向对象开发方法 开发中的名词&#xff1a; 名词间的关系 名词具体阐释 一、对象 二、消息和方法&#xff1a; 前言 本文所有知识点和内容均来自山东大学潘丽老师及山东…

京津冀协同发展:北京·光子1号金融算力中心——智能科技新高地

京津冀协同发展是党中央在新的历史条件下提出的一项重大国家战略&#xff0c;对于全面推进“五位一体”总体布局&#xff0c;以中国式现代化全面推进强国建设、民族复兴伟业&#xff0c;具有重大现实意义和深远历史意义。随着京津冀协同发展战略的深入推进&#xff0c;区域一体…

unique_ptr使用说明

背景 指针问题一直是一个比较麻烦的事情&#xff0c;比如很多人说要用智能指针完全替换掉裸指针&#xff0c;有人说要用unique_ptr, 有人建议shared_ptr,可是实际看各种经典框架&#xff0c;发现一个框架什么指针都有&#xff0c;使用的方法也是无法八门&#xff0c;这里简单说…

可访问性使命:Facebook构建无障碍社交空间

在当今数字化时代&#xff0c;社交媒体已成为人们日常生活的重要组成部分&#xff0c;而Facebook作为全球最大的社交平台之一&#xff0c;其使命不仅在于连接世界&#xff0c;还在于构建一个无障碍的社交空间&#xff0c;让每个人都能参与其中。本文将深入探讨Facebook在可访问…

几个增强诊断详解

几个增强诊断 基于CAN线 ISO15031-5是排放相关的应用层协议&#xff0c;它不关心我们使用K线还是CAN线&#xff0c;主要用于监控车辆基本参数&#xff0c;例如监控里程、车速&#xff1b;用于监控排放相关的参数&#xff0c;比如各种尾气的含量&#xff0c;氧含量等等&#xf…