It should be so simple, but I just cannot find it after being trying for an hour.
I need to get a JSON string, for example, {"k1":v1,"k2":v2}, parsed as a JsonNode.
JsonFactory factory = new JsonFactory();
JsonParser jp = factory.createJsonParser("{\"k1\":\"v1\"}");
JsonNode actualObj = jp.readValueAsTree();
gives
java.lang.IllegalStateException: No ObjectCodec defined for the parser, can not deserialize JSON into JsonNode tree
A slight variation on Richards answer but readTree can take a string so you can simplify it to:
ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.readTree("{\"k1\":\"v1\"}");
You need to use an 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);
Further documentation about creating parsers can be found here.
A third variant:
ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.readValue("{\"k1\":\"v1\"}", JsonNode.class);
Richard's answer is correct. Alternatively you can also create a MappingJsonFactory (in org.codehaus.jackson.map) which knows where to find ObjectMapper. The error you got was because the regular JsonFactory (from core package) has no dependency to ObjectMapper (which is in the mapper package).
But usually you just use ObjectMapper and do not worry about JsonParser or other low level components -- they will just be needed if you want to data-bind parts of stream, or do low-level handling.
import com.github.fge.jackson.JsonLoader;
JsonLoader.fromString("{\"k1\":\"v1\"}")
== JsonNode = {"k1":"v1"}
New approach to old question.
A solution that works from java 9+
ObjectNode agencyNode = new ObjectMapper().valueToTree(Map.of("key", "value"));
is more readable and maintainable for complex objects. 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);
Related
I am using jackson 2.8.4 and try to pretty-print (i.e. format nicely with indentation) some JSON that I have got in a one-line String called json.
I tried
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
and
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
json = mapper.writeValueAsString(json);
but the JSON String json still is just one line.
EDIT:
Before:
{"artifacts":[{"general":{"name":"jersey-client-2.26.jar","path":"doartifac/spielwiese-group-cache/org/glassfish/jersey/core/jersey-client/2.26/jersey-client-2.26.jar","pkg_type":"Maven","sha256":"3e44b7db8691eb0b2a6751eda888150b9ba1092a5805f11e4727fd4904407a41","component_id":"org.glassfish.jersey.core:jersey-client:2.26"},"issues":[],"licenses":[{"name":"CDDL-1.0","full_name":"Common Development and Distribution License (CDDL)\n 1.0","more_info_url":["http://www.opensource.org/licenses/cddl1.php","https://spdx.org/licenses/CDDL-1.0","https://spdx.org/licenses/CDDL-1.0.html","http://www.opensource.org/licenses/cddl1"],"components":["gav://org.glassfish.jersey.core:jersey-client:2.26"]},{"name":"GPL-2.0","full_name":"The GNU General Public License Version 2","more_info_url":["http://www.opensource.org/licenses/GPL-2.0","http://www.opensource.org/licenses/gpl-2.0.php","https://spdx.org/licenses/GPL-2.0","https://spdx.org/licenses/GPL-2.0.html","http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html"],"components":["gav://org.glassfish.jersey.core:jersey-client:2.26"]}]}]}
After:
"{\"artifacts\":[{\"general\":{\"name\":\"jersey-client-2.26.jar\",\"path\":\"doartifac/spielwiese-group-cache/org/glassfish/jersey/core/jersey-client/2.26/jersey-client-2.26.jar\",\"pkg_type\":\"Maven\",\"sha256\":\"3e44b7db8691eb0b2a6751eda888150b9ba1092a5805f11e4727fd4904407a41\",\"component_id\":\"org.glassfish.jersey.core:jersey-client:2.26\"},\"issues\":[],\"licenses\":[{\"name\":\"CDDL-1.0\",\"full_name\":\"Common Development and Distribution License (CDDL)\\n 1.0\",\"more_info_url\":[\"http://www.opensource.org/licenses/cddl1.php\",\"https://spdx.org/licenses/CDDL-1.0\",\"https://spdx.org/licenses/CDDL-1.0.html\",\"http://www.opensource.org/licenses/cddl1\"],\"components\":[\"gav://org.glassfish.jersey.core:jersey-client:2.26\"]},{\"name\":\"GPL-2.0\",\"full_name\":\"The GNU General Public License Version 2\",\"more_info_url\":[\"http://www.opensource.org/licenses/GPL-2.0\",\"http://www.opensource.org/licenses/gpl-2.0.php\",\"https://spdx.org/licenses/GPL-2.0\",\"https://spdx.org/licenses/GPL-2.0.html\",\"http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html\"],\"components\":[\"gav://org.glassfish.jersey.core:jersey-client:2.26\"]}]}]}"
try to check this one: Convert JSON String to Pretty Print JSON output using Jackson
You need first read existing JSON to Object, then serialize it.
Because now you are just serializing string.
UPD: You need to doo something like this:
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String json = "here your ugly json";
Object jsonObject = mapper.readValue(json, Object.class);
String prettyFormatted = mapper.writeValueAsString(jsonObject);
I have got stuck trying to insert a JSONArray into a Jackson ObjectNode. This is what I am trying to do:
public void myMethod(JSONArray jsonArray) {
ObjectNode payload = objectMapper.createObjectNode(0);
payload.put("array", /* jsonArray */);
payload.put(/* some other things */);
...
}
It feels like something really silly but what is actually the best way to do it?!
EDIT: I am sorry beacause I did not mention an important point, that is I have to serialize the ObjectNode once I finished building it, so using putPOJO() is not a possibility.
I like aribeiro's approach more. You can use the putPOJO() method to do this. For example:
// Incoming org.json.JSONArray.
JSONArray incomingArray = new JSONArray("[\"Value1\",\"Value2\"]");
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode payload = objectMapper.createObjectNode();
// Adds the JSONArray node to the payload as POJO (plain old Java object).
payload.putPOJO("array", incomingArray);
System.out.println(objectMapper.writeValueAsString(payload));
Javadoc can be found here.
Note: here's a previous implementation that I submitted using readTree():
// Incoming org.json.JSONArray.
JSONArray incomingArray = new JSONArray("[\"Value1\",\"Value2\"]");
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode payload = objectMapper.createObjectNode();
// Reads the JSON array into a Jackson JsonNode.
JsonNode jsonNode = objectMapper.readTree(incomingArray.toString());
// Sets the Jackson node on the payload.
payload.set("array", jsonNode);
System.out.println(objectMapper.writeValueAsString(payload));
The documentation in Jackson is horrible and it only states how it is possible to create JSON from objects and streams, not piece by piece. I cannot find the term to be able to search for more examples/documentation.
I would like to do something like the following.
JsonObject jsonObject = new JsonObject().add("type", "unregister").add("id",id);
return jsonObject.toString();
Which would return {"type":"unregister","id":2} as an example. Can anyone nudge me in the right direction?
The corresponding JsonObject in Jackson is ObjectNode. You can use its various xyzNode(...) factory methods to produce JsonNode subtype instances. You can then use ObjectNode#set(String, JsonNode) to add them.
JsonNodeFactory nc = new JsonNodeFactory(false); // or true, depending
ObjectNode root = new ObjectNode(nc);
TextNode text = root.textNode("unregister");
NumericNode id = root.numberNode(2);
root.set("type", text);
root.set("id", id);
Then
System.out.println(node);
produces
{"type":"unregister","id":2}
You can also create an ObjectNode through the ObjectMapper which uses the ObjectMapper's JsonNodeFactory.
ObjectMapper mapper = new ObjectMapper();
ObjectNode root = mapper.createObjectNode();
Jackson maps Java Objects to JSON, so their documentation is telling you what it does (it does not provide a sort of builder API to arbitrarily compose JSON documents)
If you want to map arbitrary key/values, use a Map<String, Object> and use Jackson to turn it into JSON. You can mix heterogeneous map values and get the result you want this way, pseudo:
Map<String, Object> map = new HashMap<>();
map.put("type", "unregister");
map.put("id", id);
StringWriter sw = new StringWriter();
mapper.writeValue(sw, map); // mapper is a ObjectMapper instance
System.out.println(sw.toString());
First of all could anyone explain to me What are differences between ObjectNode and JsonNode, and where they used?
Then if I want to convert a JSON string into ObjectNode what can I do?
You can do:
ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.valueToTree("{\"k1\":\"v1\"}")
JsonNode it is a super class of ObjectNode.
You can find the differences in the API.
I am generating jsonschema from java using the jackson classes:
ObjectMapper mapper = new ObjectMapper();
JsonSchema jsonSchema = mapper.generateJsonSchema(Sample.class);
ObjectNode node = jsonSchema.getSchemaNode();
ObjectWriter or = mapper.defaultPrettyPrintingWriter();
or.writeValue(System.out, node);
This works fine, but I was wondering how I might get descriptions added, e.g. from the type javadoc.