Bagaimana cara mengurai string JSON ke JsonNode di Jackson?


231

Seharusnya sangat sederhana, tapi aku tidak bisa menemukannya setelah mencoba selama satu jam #membuat.

Saya perlu mendapatkan string JSON, misalnya {"k1":v1,"k2":v2},, diuraikan sebagai a JsonNode.

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

memberi

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


54
#embarrasing- tidak. Jika hal-hal sederhana tidak sederhana, maka perancang API telah gagal, bukan Anda.
jameshfisher

@ StaxMan jawaban dalam kode: JsonFactory factory = new MappingJsonFactory ();
Juan Rojas

Jawaban:


371

Sedikit variasi pada jawaban Richards tetapi readTreedapat mengambil string sehingga Anda dapat menyederhanakannya menjadi:

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

44
Bagi siapa saja yang membutuhkan ObjectNodedaripada JsonNodemenggunakanmapper.valueToTree("{\"k1\":\"v1\"}")
Matius Herbst

5
@MatthewHerbst Di 2.5.1, ini membuat simpul teks baru dengan string "{\" k1 \ ": \" v1 \ "}" daripada mem-parsingnya sebagai JSON.
minexew

69

Anda perlu menggunakan 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);

Dokumentasi lebih lanjut tentang membuat parser dapat ditemukan di sini .


Apakah mungkin untuk mengambil JsonNode, memodifikasinya sedikit, dan kemudian memanggil mapper.readValue (node, class); dan keluar kelas?
portforwardpodcast

1
Iya. Bahkan ada alias untuk itu mapper.treeToValue(),. Tetapi readValue()juga berhasil.
StaxMan

Tautan itu tampaknya rusak
manuna

28

Varian ketiga:

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

Apa yang sebenarnya lewat di JsonNode.class membawa Anda ke sini?
David

3
@ David: Tidak ada, jadi varian slashnick jelas lebih baik jika Anda hanya menginginkan a JsonNode. Namun, Anda biasanya tidak menginginkannya JsonNode, jadi saya ingin menunjukkan bagaimana cara memberi tahu Jackson nilai seperti apa yang Anda inginkan.
qerub

Bagi saya, passing JsonNodetampaknya perlu untuk mencegah Jackson deserialisasi sebagai sesuatu yang lain - yang akan gagal.
Cory Klein

5

Jawaban Richard benar. Atau Anda juga dapat membuat MappingJsonFactory(di org.codehaus.jackson.map) yang tahu di mana menemukannya ObjectMapper. Kesalahan yang Anda dapatkan adalah karena reguler JsonFactory(dari corepaket) tidak memiliki ketergantungan ke ObjectMapper(yang ada dalam mapperpaket).

Tetapi biasanya Anda hanya menggunakan ObjectMapperdan tidak mengkhawatirkan JsonParseratau komponen tingkat rendah lainnya - mereka hanya akan diperlukan jika Anda ingin mengikat bagian-bagian aliran data, atau melakukan penanganan tingkat rendah.


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

0

Pendekatan baru terhadap pertanyaan lama. Solusi yang berfungsi dari java 9+

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

lebih mudah dibaca dan dipelihara untuk objek yang kompleks. 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);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.