Chuyển đổi JSON thành bản đồ


190

Cách tốt nhất để chuyển đổi mã JSON như thế này là gì:

{ 
    "data" : 
    { 
        "field1" : "value1", 
        "field2" : "value2"
    }
}

trong Bản đồ Java, trong đó một khóa là (field1, field2) và các giá trị cho các trường đó là (value1, value2).

Có ý kiến ​​gì không? Tôi có nên sử dụng Json-lib cho điều đó? Hoặc tốt hơn nếu tôi viết trình phân tích cú pháp của riêng tôi?


Tôi đã viết mã cho điều này mà không cần sử dụng bất kỳ thư viện. stackoverflow.com/questions/21720759/jsonobject-to-map/
Kẻ

Câu trả lời:


335

Tôi hy vọng bạn đã nói đùa về việc viết trình phân tích cú pháp của riêng bạn. :-)

Đối với ánh xạ đơn giản như vậy, hầu hết các công cụ từ http://json.org (phần java) sẽ hoạt động. Đối với một trong số họ (Jackson https://github.com/FasterXML/jackson-databind/#5-minute-tutorial-streaming-parser-generator ), bạn sẽ làm:

Map<String,Object> result =
        new ObjectMapper().readValue(JSON_SOURCE, HashMap.class);

(trong đó JSON_SOURCE là một chuỗi tệp, luồng đầu vào, trình đọc hoặc chuỗi nội dung json)


36
Hơn nữa, nếu bạn muốn một Bản đồ được gõ (khai thác các tổng quát java), bạn có thể thực hiện: Map <String, MyPojo> typedMap = mapper.readValue (jsonStream, TypeReference mới <Map <String, MyPojo >> () {});
obe6

5
Nếu bạn làm việc với dự án Maven, bạn sẽ cần <lệ thuộc> <groupId> com.fasterxml.jackson.core </ groupId> <artifactId> jackson-databind </ artifactId> <version> 2.4.4 </ version> >
LoBo

2
Và có vẻ như Jackson đã chuyển từ 09 vì vậy: Jackson data-bind
jacob.mccrumb

@ obe6 Tôi đoán OP không đùa. Bạn có thể tìm thấy một "JSON" duy nhất ở bất cứ đâu trong đoạn mã của bạn ngoài tên biến tùy ý đó không? Tôi cũng đang vật lộn vì những cái tên trong Jackson API.
Aetherus

FWTW, trong khi câu trả lời của @ obe6 là chính xác về mặt kỹ thuật, bạn cũng có thể sử dụng hình thức ngắn hơn : Map<String,Object> result = mapper.readValue(source, Map.class).
StaxMan

35

Sử dụng thư viện GSON:

import com.google.gson.Gson;
import com.google.common.reflect.TypeToken;
import java.lang.reclect.Type;

Sử dụng mã sau đây:

Type mapType = new TypeToken<Map<String, Map>>(){}.getType();  
Map<String, String[]> son = new Gson().fromJson(easyString, mapType);

7
java tốt nhất: TypeToken<Map<String, Map>>:-)
froderik

2
Với TypeToken <Map <String, Object >> mới, nó cũng sẽ hoạt động khi có các mảng bên trong.
9ilsdx 9rvj 0lo

33

Tôi thích thư viện google gson .
Khi bạn không biết cấu trúc của json. Bạn có thể dùng

JsonElement root = new JsonParser().parse(jsonString);

và sau đó bạn có thể làm việc với json. ví dụ: làm thế nào để có được "value1" từ gson của bạn:

String value1 = root.getAsJsonObject().get("data").getAsJsonObject().get("field1").getAsString();

19
Điều này có thể ném NullPulumExceptions 5 cách khác nhau nếu bạn nhận được dữ liệu không mong muốn.
dfraser

Bạn có thể sử dụng .path () ngay bây giờ và nó sẽ không ném NPE
C2H50H

18

Sử dụng JSON lib Ví dụ: http://www.json.org/java/

// Assume you have a Map<String, String> in JSONObject jdata
@SuppressWarnings("unchecked")
Iterator<String> nameItr = jdata.keys();
Map<String, String> outMap = new HashMap<String, String>();
while(nameItr.hasNext()) {
    String name = nameItr.next();
    outMap.put(name, jdata.getString(name));

}

12

Bài đăng của tôi có thể hữu ích cho người khác, vì vậy hãy tưởng tượng bạn có một bản đồ với một đối tượng cụ thể trong các giá trị, đại loại như thế:

{  
   "shopping_list":{  
      "996386":{  
         "id":996386,
         "label":"My 1st shopping list",
         "current":true,
         "nb_reference":6
      },
      "888540":{  
         "id":888540,
         "label":"My 2nd shopping list",
         "current":false,
         "nb_reference":2
      }
   }
}

Để phân tích tệp JSON này với thư viện GSON, thật dễ dàng: nếu dự án của bạn bị sai lệch

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.3.1</version>
</dependency>

Sau đó sử dụng đoạn mã này:

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

//Read the JSON file
JsonElement root = new JsonParser().parse(new FileReader("/path/to/the/json/file/in/your/file/system.json"));

//Get the content of the first map
JsonObject object = root.getAsJsonObject().get("shopping_list").getAsJsonObject();

//Iterate over this map
Gson gson = new Gson();
for (Entry<String, JsonElement> entry : object.entrySet()) {
    ShoppingList shoppingList = gson.fromJson(entry.getValue(), ShoppingList.class);
    System.out.println(shoppingList.getLabel());
}

POJO tương ứng phải là một cái gì đó như thế:

public class ShoppingList {

    int id;

    String label;

    boolean current;

    int nb_reference;

    //Setters & Getters !!!!!
}

Hy vọng nó giúp !


5

Bằng cách này, nó hoạt động như một Bản đồ ...

JSONObject fieldsJson = new JSONObject(json);
String value = fieldsJson.getString(key);

<dependency>
    <groupId>org.codehaus.jettison</groupId>
    <artifactId>jettison</artifactId>
    <version>1.1</version>
</dependency>

1
Có, nhưng bạn phải gói mọi đơn giản trong thử / bắt vì ngoại lệ JSON.
Maciej Swic

1
bạn có thể viết một lớp, JsonMap implements Map<String,Objectđể bọc JSONObject. Sau đó, bạn có được Mapgiao diện thực sự .
Jeffrey Blattman

Vui lòng thêm các thư viện đã sử dụng.
mvermand

5

Tôi làm theo cách này. Thật đơn giản.

import java.util.Map;
import org.json.JSONObject;
import com.google.gson.Gson;

public class Main {
    public static void main(String[] args) {
        JSONObject jsonObj = new JSONObject("{ \"f1\":\"v1\"}");
        @SuppressWarnings("unchecked")
        Map<String, String> map = new Gson().fromJson(jsonObj.toString(),Map.class);
        System.out.println(map);
    }
}

Tôi đã thử phương pháp này nhưng nó không hoạt động ... bạn có thể trả lời cho điều này không? stackoverflow.com/questions/60329223/ từ
Siva

3
java.lang.reflect.Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Gson gson = new Gson();
Map<String, Object> categoryicons = gson.fromJson(json, mapType );


2

Với Gson 2.7 của google (có thể là các phiên bản trước đó, nhưng tôi đã thử nghiệm 2.7) đơn giản như:

Map map = gson.fromJson(json, Map.class);

Trả về Bản đồ loại class com.google.gson.internal.LinkedTreeMapvà hoạt động đệ quy trên các đối tượng lồng nhau.


1

Một lựa chọn khác là json-đơn giản có thể được tìm thấy trong Maven Central :

(JSONObject)JSONValue.parse(someString); //JSONObject is actually a Map.

Hiện vật là 24kbyte, không có phụ thuộc thời gian chạy khác.


Tôi lấy nulllại từ một chuỗi JSON đơn giản trong đó một trong các giá trị là một chuỗi các chuỗi.
isapir

1

Nếu bạn đang sử dụng org.json, JSONObject có một phương thức toMap(). Bạn có thể dễ dàng làm:

Map<String, Object> myMap = myJsonObject.toMap();

0
import net.sf.json.JSONObject

JSONObject.fromObject(yourJsonString).toMap

0

Thư viện Underscore-java có thể chuyển đổi chuỗi json thành bản đồ băm. Tôi là người duy trì dự án.

Mã ví dụ:

import com.github.underscore.lodash.U;
import java.util.*;

public class Main {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        String json = "{"
            + "    \"data\" :"
            + "    {"
            + "        \"field1\" : \"value1\","
            + "        \"field2\" : \"value2\""
            + "    }"
            + "}";

       Map<String, Object> data = (Map) U.get((Map<String, Object>) U.fromJson(json), "data");
       System.out.println(data);

       // {field1=value1, field2=value2}
    }
}

0

Nếu bạn cần Java thuần mà không có bất kỳ sự phụ thuộc nào, bạn có thể sử dụng API xây dựng trong Nashorn API từ Java 8. Nó không được dùng trong Java 11.

Điều này làm việc cho tôi:

...
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
...

public class JsonUtils {

    public static Map parseJSON(String json) throws ScriptException {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("javascript");

        String script = "Java.asJSONCompatible(" + json + ")";

        Object result = engine.eval(script);

        return (Map) result;
    }
}

Sử dụng mẫu

JSON:

{
    "data":[
        {"id":1,"username":"bruce"},
        {"id":2,"username":"clark"},
        {"id":3,"username":"diana"}
    ]
}

Mã số:

...
import jdk.nashorn.internal.runtime.JSONListAdapter;
...

public static List<String> getUsernamesFromJson(Map json) {
    List<String> result = new LinkedList<>();

    JSONListAdapter data = (JSONListAdapter) json.get("data");

    for(Object obj : data) {
        Map map = (Map) obj;
        result.add((String) map.get("username"));
    }

    return result;
}

-1

JSON to Map luôn là kiểu dữ liệu chuỗi / đối tượng. tôi đã gửi lib GSON từ google.

hoạt động rất tốt và JDK 1.5 là yêu cầu tối thiểu.


1
Bạn đã sử dụng GSON như thế nào?
NinjaCoder
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.