杰瑞科技汇

Java JSON如何转Map?

Of course! Converting a JSON string to a Java Map is a very common task. The most popular and robust way to do this is by using a dedicated JSON library. The two most widely used libraries are Jackson and Gson.

Java JSON如何转Map?-图1
(图片来源网络,侵删)

I'll show you how to do it with both, starting with Jackson, which is often the preferred choice for new projects.


Using Jackson (Recommended)

Jackson is a powerful, high-performance library for processing JSON. It's the de-facto standard in many Java frameworks, including Spring.

Step 1: Add the Jackson Dependency

You need to include the Jackson Databind library in your project.

Maven (pom.xml):

Java JSON如何转Map?-图2
(图片来源网络,侵删)
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- Use the latest version -->
</dependency>

Gradle (build.gradle):

implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2' // Use the latest version

Step 2: Write the Java Code

The key class is ObjectMapper. Its readValue() method can parse a JSON string and convert it into any Java object, including a Map.

The target map will typically be Map<String, Object>, where the Object can be a String, Number, Boolean, List, or another Map.

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class JacksonJsonToMapExample {
    public static void main(String[] args) {
        // The JSON string we want to convert
        String jsonString = "{\"name\":\"John Doe\",\"age\":30,\"isStudent\":false,\"courses\":[\"History\",\"Math\"],\"address\":{\"street\":\"123 Main St\",\"city\":\"Anytown\"}}";
        // Create an instance of ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Use readValue with a TypeReference to specify the exact Map type
            // This is crucial for handling nested objects and arrays correctly.
            Map<String, Object> dataMap = objectMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});
            // Print the resulting map
            System.out.println("Successfully converted JSON to Map:");
            dataMap.forEach((key, value) -> {
                System.out.println(key + " : " + value + " (Type: " + value.getClass().getSimpleName() + ")");
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output:

Successfully converted JSON to Map:
name : John Doe (Type: String)
age : 30 (Type: Integer)
isStudent : false (Type: Boolean)
courses : [History, Math] (Type: ArrayList)
address : {street=123 Main St, city=Anytown} (Type: LinkedHashMap)

Key Points:

Java JSON如何转Map?-图3
(图片来源网络,侵删)
  • ObjectMapper: The central class for reading and writing JSON.
  • readValue(String, TypeReference): This is the most flexible method. The TypeReference allows you to specify complex generic types like Map<String, Object>. Without it, Jackson might not correctly infer the type for nested structures.
  • Nested Objects: A JSON object like "address": {...} becomes a LinkedHashMap inside the main map.
  • Arrays: A JSON array like "courses": [...] becomes an ArrayList.

Using Gson

Gson is another excellent library from Google, known for its simplicity and ease of use.

Step 1: Add the Gson Dependency

Maven (pom.xml):

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version> <!-- Use the latest version -->
</dependency>

Gradle (build.gradle):

implementation 'com.google.code.gson:gson:2.10.1' // Use the latest version

Step 2: Write the Java Code

Gson's JsonParser is used to parse the string into a tree structure (JsonElement), which you then convert to a Map.

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.Map;
import java.util.Set;
public class GsonJsonToMapExample {
    public static void main(String[] args) {
        // The JSON string we want to convert
        String jsonString = "{\"name\":\"Jane Doe\",\"age\":25,\"isStudent\":true,\"courses\":[\"Science\",\"Art\"],\"address\":{\"street\":\"45 Oak Ave\",\"city\":\"Otherville\"}}";
        // Create an instance of Gson
        Gson gson = new Gson();
        try {
            // 1. Parse the JSON string into a JsonElement tree
            JsonElement jsonElement = JsonParser.parseString(jsonString);
            // 2. Check if the root is a JsonObject (equivalent to a JSON object)
            if (jsonElement.isJsonObject()) {
                JsonObject jsonObject = jsonElement.getAsJsonObject();
                // 3. Convert the JsonObject to a Map
                // The helper method iterates through the entry set and converts values.
                Map<String, Object> dataMap = gson.fromJson(jsonObject, new com.google.gson.reflect.TypeToken<Map<String, Object>>() {}.getType());
                // Print the resulting map
                System.out.println("Successfully converted JSON to Map:");
                dataMap.forEach((key, value) -> {
                    System.out.println(key + " : " + value + " (Type: " + value.getClass().getSimpleName() + ")");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Note: For Gson, you also need a TypeToken to handle the generic Map<String, Object> type correctly, similar to Jackson's TypeReference.

Output:

Successfully converted JSON to Map:
name : Jane Doe (Type: String)
age : 25.0 (Type: Double)
isStudent : true (Type: Boolean)
courses : [Science, Art] (Type: ArrayList)
address : {street=45 Oak Ave, city=Otherville} (Type: LinkedTreeMap)

Key Points:

  • JsonParser: Used to parse the JSON string into a JsonElement.
  • JsonObject: Represents a JSON object (a collection of key-value pairs).
  • gson.fromJson(JsonObject, TypeToken): Converts the parsed JsonObject into a Java Map. Gson uses LinkedTreeMap by default for JSON objects.
  • TypeToken: Required to specify the generic type Map<String, Object>.

Comparison and When to Use Which

Feature Jackson Gson
Performance Generally faster and has a smaller memory footprint. Very good performance, but usually slightly slower than Jackson.
Features Extremely rich. Supports streaming API, tree model, data binding, and integrates deeply with frameworks like Spring. Simpler and more focused. Easier to get started with for basic tasks.
API Powerful but can have a steeper learning curve due to its many features (e.g., ObjectMapper, TypeReference). Very straightforward and intuitive API (JsonParser, JsonElement).
Default Types Uses LinkedHashMap for JSON objects. Uses LinkedTreeMap for JSON objects.
Error Handling Provides detailed and often helpful exceptions. Also provides good error messages.

Recommendation:

  • Use Jackson if you are working on any serious project, especially a web application using a framework like Spring Boot. It's the industry standard for a reason and offers the best performance and features.
  • Use Gson if you need a quick and simple solution for a smaller project or if you prefer its more straightforward API. It's also a great choice if you're already using other Google libraries in your project.

Important Considerations

  1. Handling Map<String, Object>: Be aware that the values in your map are of type Object. You will need to cast them to their specific types (e.g., (String) map.get("name"), (List<String>) map.get("courses")) before you can use their methods. This can lead to ClassCastException if the JSON structure doesn't match your expectations.

  2. Security: Never parse JSON from an untrusted source directly without validation or using a safe parser. Malicious JSON can lead to attacks like Denial of Service (DoS). Modern JSON libraries are generally safe, but it's always good practice to be aware of the risks. Libraries like Jackson have features to mitigate this (e.g., JsonParser.Feature.STRICT_DUPLICATE_DETECTION).

分享:
扫描分享到社交APP
上一篇
下一篇