2010-09-06 38 views
179

Nó phải đơn giản như vậy, nhưng tôi không thể tìm thấy nó sau khi thử #mbarrasing một giờ.Làm thế nào để phân tích chuỗi JSON thành JsonNode ở Jackson?

Tôi cần nhận chuỗi JSON, ví dụ: {"k1":v1,"k2":v2}, được phân tích cú pháp là 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

+38

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

Trả lời

303

Một biến thể nhẹ trên Richards câu trả lời nhưng readTree có thể mất một chuỗi, do đó bạn có thể đơn giản hóa nó để:

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

Đối với bất kỳ ai cần 'ObjectNode' thay vì sử dụng' JsonNode' 'mapper.valueToTree (" {\ "k1 \": \ "v1 \"} ")' –

+5

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

59

Bạn cần phải sử dụng một ObjectMapper như here: Câu trả lời

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); 
+0

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 ngoài một lớp học? – portforwardpodcast

+1

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

5

Richard là đúng. Hoặc bạn cũng có thể tạo một MappingJsonFactory (trong org.codehaus.jackson.map) để biết nơi tìm thấy ObjectMapper. Lỗi bạn nhận được là do số JsonFactory thông thường (từ gói core) không phụ thuộc vào ObjectMapper (nằm trong gói mapper).

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

24

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

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

Điều gì đã vượt qua trong JsonNode.class thực sự giúp bạn có được ở đây? – David

+3

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

+0

Đối với tôi, việc vượt qua 'JsonNode' rõ ràng là cần thiết để ngăn Jackson khỏi việc deserializing nó như một cái gì đó khác - điều đó sẽ thất bại. –

3
import com.github.fge.jackson.JsonLoader; 
JsonLoader.fromString("{\"k1\":\"v1\"}") 
== JsonNode = {"k1":"v1"} 
Các vấn đề liên quan