Làm cách nào để phân tích chuỗi JSON thành JsonNode ở Jackson?


231

Nó rất đơn giản, nhưng tôi không thể tìm thấy nó sau khi thử một giờ #embarrasing.

Tôi cần lấy một chuỗi JSON, ví dụ {"k1":v1,"k2":v2}, được phân tích cú pháp như một JsonNode.

JsonFactory factory = new JsonFactory();
JsonParser jp = factory.createJsonParser("{\"k1\":\"v1\"}");
JsonNode actualObj = jp.readValueAsTree();

cho

java.lang.IllegalStateException: No ObjectCodec defined for the parser, can not deserialize JSON into JsonNode tree


54
#embarrasing- Không. Nếu những điều đơn giản không đơn giản, thì trình thiết kế API đã thất bại, không phải bạn.
jameshfisher

Câu trả lời của @ StaxMan trong mã: JsonFactory Factory = new MappingJsonFactory ();
Juan Rojas

Câu trả lời:


371

Một biến thể nhỏ trên câu trả lời của Richards nhưng readTreecó thể lấy một chuỗi để bạn có thể đơn giản hóa nó thành:

ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.readTree("{\"k1\":\"v1\"}");

44
Đối với bất cứ ai cần sử dụng ObjectNodehơn là JsonNodesử dụngmapper.valueToTree("{\"k1\":\"v1\"}")
Matthew Herbst

5
@MatthewHerbst Trong 2.5.1, điều này tạo ra một nút văn bản mới với chuỗi "{\" k1 \ ": \" v1 \ "}" thay vì phân tích cú pháp dưới dạng JSON.
minexew

69

Bạn cần sử dụng một ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
JsonFactory factory = mapper.getJsonFactory(); // since 2.1 use mapper.getFactory() instead
JsonParser jp = factory.createJsonParser("{\"k1\":\"v1\"}");
JsonNode actualObj = mapper.readTree(jp);

Tài liệu thêm về việc tạo phân tích cú pháp có thể được tìm thấy ở đây .


Có thể lấy JsonNode, sửa đổi nó một chút và sau đó gọi mapper.readValue (nút, lớp); và ra khỏi lớp?
portforwardpodcast

1
Đúng. Thậm chí còn có một bí danh cho điều đó , mapper.treeToValue(). Nhưng readValue()cũng hoạt động.
StaxMan

Liên kết dường như bị phá vỡ
manuna

28

Một biến thể thứ ba:

ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.readValue("{\"k1\":\"v1\"}", JsonNode.class);

Điều gì đã đi qua trong JsonNode. Class thực sự đưa bạn đến đây?
David

3
@David: Không có gì, vì vậy biến thể của slashnick rõ ràng là tốt hơn nếu bạn chỉ muốn a JsonNode. Tuy nhiên, bạn thường không muốn a JsonNode, vì vậy tôi muốn chỉ cho Jackson cách nói với Jackson về loại giá trị nào bạn muốn.
qerub

Đối với tôi, vượt qua JsonNoderõ ràng là cần thiết để ngăn Jackson từ bỏ nó như một thứ khác - điều sẽ thất bại.
Cory Klein

5

Câu trả lời của Richard là chính xác. Ngoài ra, bạn cũng có thể tạo một MappingJsonFactory(trong org.codehaus.jackson.map) biết nơi để tìm ObjectMapper. Lỗi bạn gặp phải là do thông thường JsonFactory(từ coregói) không có sự phụ thuộc vào ObjectMapper(trong mappergói).

Nhưng thông thường, bạn chỉ sử dụng ObjectMappervà không lo lắng về JsonParsercác thành phần cấp thấp khác - chúng sẽ chỉ cần thiết nếu bạn muốn liên kết dữ liệu các phần của luồng hoặc xử lý mức thấp.


3
import com.github.fge.jackson.JsonLoader;
JsonLoader.fromString("{\"k1\":\"v1\"}")
== JsonNode = {"k1":"v1"}

0

Cách tiếp cận mới cho câu hỏi cũ. Một giải pháp hoạt động từ java 9+

ObjectNode agencyNode = new ObjectMapper().valueToTree(Map.of("key", "value"));

dễ đọc hơn và có thể bảo trì cho các đối tượng phức tạp. Ej

Map<String, Object> agencyMap = Map.of(
        "name", "Agencia Prueba",
        "phone1", "1198788373",
        "address", "Larrea 45 e/ calligaris y paris",
        "number", 267,
        "enable", true,
        "location", Map.of("id", 54),
        "responsible", Set.of(Map.of("id", 405)),
        "sellers", List.of(Map.of("id", 605))
);
ObjectNode agencyNode = new ObjectMapper().valueToTree(agencyMap);
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.