java中常用的json,jsonarray,map数据结构与对象互转详解

好的,我们来详细讲解 Java 中 JSONJSONArrayMap 以及普通 Java Bean(对象)之间的相互转换。这是一个在日常开发中极其常见的需求,尤其是在处理 Web API 请求和响应时。

我们将以目前最主流的 JSON 库 ​Jackson​ 和 ​Fastjson​ 为例进行讲解。虽然 Gson 也很流行,但其设计理念与这两者略有不同,但核心概念相通。

图片[1]_java中常用的json,jsonarray,map数据结构与对象互转详解_知途无界

1. 核心概念与依赖准备

1.1 数据结构定义

  • Java Bean (Object)​​: 一个普通的 Java 类,拥有私有字段、Getter 和 Setter 方法。它是我们业务数据的载体。 public class User { private String name; private int age; private List<String> hobbies; // 也可以是其他对象或集合 // 必须有无参构造函数 public User() {} public User(String name, int age, List<String> hobbies) { this.name = name; this.age = age; this.hobbies = hobbies; } // Getter and Setter ... @Override public String toString() { return "User{name='" + name + "', age=" + age + ", hobbies=" + hobbies + '}'; } }
  • Map​: java.util.Map,一种键值对集合,非常灵活,常用于动态结构或不便定义 Java Bean 的场景。
  • JSONObject​: 表示一个 JSON 对象({...}),是 JSON 库提供的类,用于程序内部操作 JSON 数据。
  • JSONArray​: 表示一个 JSON 数组([...]),同样是 JSON 库提供的类。

1.2 引入依赖 (Maven)

Jackson:​

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.3</version> <!-- 使用最新版本 -->
</dependency>

Fastjson:​

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.34</version> <!-- 推荐使用 Fastjson 2.x -->
</dependency>

2. Jackson 库详解

Jackson 的核心类是 ObjectMapper

2.1 Object -> JSON (序列化)

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;

public class JacksonExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        // 1. Object to JSON String
        User user = new User("Alice", 25, Arrays.asList("Reading", "Gaming"));
        String jsonString = mapper.writeValueAsString(user);
        System.out.println("Object to JSON String: " + jsonString);
        // 输出: {"name":"Alice","age":25,"hobbies":["Reading","Gaming"]}

        // 2. Object to JSONObject (Jackson 默认不直接提供 JSONObject,但可以转成 Map 或 JsonNode)
        // 常用做法:先转成 Map,或使用 Jackson 的 JsonNode
        Map<String, Object> userMap = mapper.convertValue(user, Map.class);
        System.out.println("Object to Map: " + userMap);

        // 或者使用 JsonNode (更接近 JSONObject 的概念)
        // JsonNode jsonNode = mapper.valueToTree(user);
    }
}

2.2 JSON -> Object (反序列化)

// 接上面的代码
public class JacksonExample {
    // ... main 方法内继续

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        String jsonString = "{\"name\":\"Bob\",\"age\":30,\"hobbies\":[\"Cooking\",\"Hiking\"]}";

        // 1. JSON String to Object
        User userFromJson = mapper.readValue(jsonString, User.class);
        System.out.println("JSON String to Object: " + userFromJson);

        // 2. JSON String to Map
        Map<String, Object> mapFromJson = mapper.readValue(jsonString, Map.class);
        System.out.println("JSON String to Map: " + mapFromJson);
        // 注意:hobbies 在 Map 里是 ArrayList

        // 3. JSON String to JsonNode (可以像操作树一样操作)
        // JsonNode rootNode = mapper.readTree(jsonString);
        // String name = rootNode.get("name").asText();
        // int age = rootNode.get("age").asInt();
    }
}

2.3 Map <-> JSON

ObjectMapper mapper = new ObjectMapper();

// Map to JSON String
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("id", 1001);
dataMap.put("active", true);
dataMap.put("tags", new String[]{"vip", "new"});
String mapJsonString = mapper.writeValueAsString(dataMap);
System.out.println("Map to JSON: " + mapJsonString);

// JSON String to Map
Map<String, Object> mapFromJson = mapper.readValue(mapJsonString, Map.class);
System.out.println("JSON to Map: " + mapFromJson);

2.4 处理 JSONArray

Jackson 将 JSON 数组视为 List

ObjectMapper mapper = new ObjectMapper();

// List<Object> to JSON Array String
List<User> users = Arrays.asList(
    new User("Alice", 25, Arrays.asList("Reading")),
    new User("Bob", 30, Arrays.asList("Gaming"))
);
String jsonArrayString = mapper.writeValueAsString(users);
System.out.println("List to JSON Array: " + jsonArrayString);
// 输出: [{"name":"Alice","age":25,...}, {"name":"Bob","age":30,...}]

// JSON Array String to List<Object>
// 方式1:使用 TypeReference 来保留泛型信息
List<User> usersFromJson = mapper.readValue(jsonArrayString, new TypeReference<List<User>>() {});
System.out.println("JSON Array to List: " + usersFromJson);

// 方式2:转成 List<Map>
List<Map<String, Object>> listOfMaps = mapper.readValue(jsonArrayString, new TypeReference<List<Map<String, Object>>>() {});

3. Fastjson 库详解

Fastjson 的 API 非常直观,核心类是 JSON

3.1 Object -> JSON

import com.alibaba.fastjson2.JSON;
import java.util.*;

public class FastjsonExample {
    public static void main(String[] args) {
        // 1. Object to JSON String
        User user = new User("Alice", 25, Arrays.asList("Reading", "Gaming"));
        String jsonString = JSON.toJSONString(user);
        System.out.println("Object to JSON String: " + jsonString);

        // 2. Object to JSONObject
        // Fastjson 可以直接将 Object 转为 JSONObject
        // 但通常我们直接使用 JSON.toJSONString 或 JSON.toJSON

        // 3. List/Array to JSONArray String
        List<User> users = Arrays.asList(user, new User("Bob", 30, null));
        String jsonArrayString = JSON.toJSONString(users);
        System.out.println("List to JSONArray: " + jsonArrayString);
    }
}

3.2 JSON -> Object

// 接上面的代码
public class FastjsonExample {
    public static void main(String[] args) {
        String jsonString = "{\"name\":\"Bob\",\"age\":30,\"hobbies\":[\"Cooking\",\"Hiking\"]}";
        String jsonArrayString = "[{\"name\":\"Alice\",...}, {\"name\":\"Bob\",...}]";

        // 1. JSON String to Object
        User user = JSON.parseObject(jsonString, User.class);
        System.out.println("JSON to Object: " + user);

        // 2. JSON String to Map
        Map<String, Object> map = JSON.parseObject(jsonString, Map.class);
        System.out.println("JSON to Map: " + map);

        // 3. JSONArray String to List<Object>
        List<User> users = JSON.parseArray(jsonArrayString, User.class);
        System.out.println("JSONArray to List: " + users);

        // 4. JSONArray String to List<Map>
        List<Map<String, Object>> listOfMaps = JSON.parseArray(jsonArrayString, Map.class);
    }
}

3.3 Map <-> JSON & JSONObject 操作

// Map to JSON
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("id", 1001);
String mapJsonString = JSON.toJSONString(dataMap);

// JSON to Map
Map<String, Object> map = JSON.parseObject(mapJsonString, Map.class);

// 使用 JSONObject (类似 Jackson 的 JsonNode)
JSONObject jsonObject = (JSONObject) JSON.toJSON(user);
String name = jsonObject.getString("name");
int age = jsonObject.getIntValue("age");
JSONArray hobbies = jsonObject.getJSONArray("hobbies");

4. 总结与最佳实践

转换方向JacksonFastjson
Object → JSON StringobjectMapper.writeValueAsString(obj)JSON.toJSONString(obj)
JSON String → ObjectobjectMapper.readValue(jsonStr, Class)JSON.parseObject(jsonStr, Class)
Object → MapobjectMapper.convertValue(obj, Map.class)(Map) JSON.toJSON(obj)JSON.parseObject(JSON.toJSONString(obj), Map.class)
JSON String → MapobjectMapper.readValue(jsonStr, Map.class)JSON.parseObject(jsonStr, Map.class)
List → JSON Array StringobjectMapper.writeValueAsString(list)JSON.toJSONString(list)
JSON Array String → ListobjectMapper.readValue(jsonStr, new TypeReference<List<Class>>(){})JSON.parseArray(jsonStr, Class)

最佳实践建议:

  1. 选择库​:
    • Jackson​: Spring Boot 默认集成,性能优秀,社区强大,是业界标准。
    • Fastjson​: API 简单易用,序列化速度快,但历史上曾出现过安全漏洞,需确保使用最新版本(2.x)。
    • Gson​: Google 出品,API 简洁,易于上手。
  2. Java Bean 要求​:
    • 必须提供 ​无参公共构造函数
    • 必须为需要序列化和反序列化的字段提供 ​Getter 和 Setter​(或者配置为使用字段访问)。
  3. 处理复杂嵌套和集合​:
    • 使用 TypeReference (Jackson) 或指定 Class (Fastjson 的 parseArray) 来处理 List<MyObject>Map<String, MyObject> 等泛型集合的反序列化。
  4. 日期格式​:
    • 可以通过注解(如 @JsonFormat)或全局配置来统一处理日期序列化格式。
  5. 空值和忽略字段​:
    • 两个库都提供了丰富的注解来控制序列化行为,例如 @JsonIgnore (Jackson) / @JSONField(serialize = false) (Fastjson) 来忽略字段,@JsonInclude (Jackson) 来控制只包含非空值。

掌握这些转换技巧,就能轻松应对绝大多数 Java JSON 处理场景。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞7 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容