In Play Framework we have the helper method Json.toJson() to generate JsonNodes from the request body or DB queries, but I don't know how to remove specific fields from the object after it has been generated.
Play uses FasterXML/jackson under the hood.
For example, let's say that you want to retrieve the payload from a request. You call request().body().asJson(), in your controller and you get a JsonNode.
A JsonNode doesn't have insertion capabilities but ObjectNode has.
1. Creating an ObjectNode(showing 2 common ways to do it):
a. Casting to ObjectNode
ObjectNode json = (ObjectNode) request().body().asJson();
b. Using an ObjectMapper(gives you more control like serialization features)
ObjectMapper mapper = new ObjectMapper();
//set serialization features in cases where you need them
mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
mapper.setSerializationInclusion(Include.NON_NULL);
ObjectNode json = mapper.createObjectNode();
2. Adding/removing elements (linked the ObjectNode API so you can check all of the available methods)
json.remove("fieldName");
json.put("anotherFieldName", "yesWeCan")
.put("canWeDoBoolean", true)
.put("howAboutNumbers", 1234567890);
Don't forget to check the rest of the documentation/tutorials as jackson is a complex library and you might want to educate yourself on the subject.
Related
I am trying to parse a json received from server in different custom objects, all implement single interface. My Json looks like
I have created classes MyFile, Display, PlayList and Manager. All implement EntityIFace.
First I created a wrapper class with one element of type List and tried restTemplate.exchange but list was null.
Then I decided to read json in String and parse it.
ResponseEntity responseEntity = restTemplate.getForEntity(baseUrl, String.class);
How can I read this json String into List of EntityIFace. Is there are way I can implement custom ObjectMapper? Or any other way to read this structure?
Thanks in Advance
Found a solution ..
I am reading json in String and parsing it using code below
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(json);
JsonNode arrayNode = jsonNode.get("entities");
and Then getting entities using jsonNode.get() method.
I have a json. Lets say:
{
"id":"101",
"name":"Saurabh",
"age":"28"
}
Now, I want to add "rollNo":"52" just after id attribute.
How can I do that using jsonNode in java?
Actually I am parsing this object using jsonNode, so no pojo mapping
I just want a way to add the attribute anywhere with creating a pojo mapping.
JsonNode is immutable and is intended for parse operation. However, it can be cast into ObjectNode and add value ((ObjectNode)jsonNode).put("rollNo", "52");
JSON properties are not ordered. You cannot decide to put one "just after" another. They will be in the order they will be.
Well, that's how it's meant. If you use a Jackson streaming JSON Writer, you can use it to write the properties in the order you like. But that's jumping through hoops just to do something that you shouldn't want to do in the first place. When you want stuff in a specific order, put them in arrays.
I actually found a way to do that.
First create a new blank node, then iterate over original node and check your condition and put the new node accordingly.
This may take only fraction of time, but will resolve these kind of issues.
Here is the code
ObjectNode newChildNode = new ObjectNode(JsonNodeFactory.instance);
Iterator<Map.Entry<String, JsonNode>> fields = childNode.fields();
while(fields.hasNext()){
Map.Entry<String, JsonNode> entry = fields.next();
newChildNode.putPOJO(entry.getKey(), entry.getValue());
if("id".equals(entry.getKey())){
newChildNode.put("rollNo", "52");
}
}
//This will convert the POJO Node again to JSON node
ObjectMapper mapper = new ObjectMapper();
newChildNode= mapper.readTree(newChildNode.toString());
What is the way to generate a Java object with get and set methods?
You should write a java bean with properties maching the JSON key's, from that point since you already have a reader its a simple as
YourObject obj = gson.fromJson(br, YourObject.class);
UPDATE
With respect to your comment, when you don't want or can't create a bean it usually boils down to parsing JSON to map. GSON (afaik) doesn't have a built-in for this, but its not hard to build a method that will traverse GSON's objects. You have an example in this blog
http://itsmyviewofthings.blogspot.it/2013/04/jsonconverter-code-that-converts-json.html
As you seem to be open to alternatives, take a look at Jackson as well (the two libs are the de-facto standard in JAVA).
With jackson you don't have to create a bean to support deserialization, e.g.
String json = "{\"id\":\"masterslave\"}";
Map<String,String> map = new HashMap<String,String>();
ObjectMapper mapper = new ObjectMapper();
//convert JSON string to Map
map = mapper.readValue(json,
new TypeReference<HashMap<String,String>>(){});
http://www.jsonschema2pojo.org/
That link helps generate the Java object format based on the GSON you feed in. Just make sure you set the settings exactly as you need it. As always, it's not a good idea to just copy-paste generated code, but it might be of help.
I'm writing a JSON representation of an object to a Redis instance (via Jesque) but am unclear whether putting a JsonNode object is the right approach. The gist of examples/APIs (e.g. this one for ObjectMapper) is that I should use that if writing to a file, but I'm really looking for an Object I can send to Redis.
Here is what I have, where the JsonNode is represented below by the object payload. This works just fine but was a struggle to figure out so I assume I'm missing the happy path.
final String queueName = "myQueue";
final net.greghaines.jesque.client.Client client = getClient();
final net.greghaines.jesque.Job job = new Job(jobClassName, payload);
client.enqueue(queueName, job);
client.end();
Currently payload is a JsonNode object generated by
final ObjectMapper objectMapper = new ObjectMapper();
final Object jsonNode = objectMapper.valueToTree(this);
Is there a more preferred approach?
An alternative to storing the JsonNode representation of your object is to simply store a String representation:
new ObjectMapper().writeValueAsString(yourObject);
Then, when you retrieve the object, you can always deserialize the String representation to a JsonNode if you need to:
JsonNode actualObj = mapper.readTree(jsonString);
Or to a simple type-safe entity object:
YourEntity entity = mapper.readValue(jsonAsString, YourEntity.class);
All without storing library specific information in Redis.
Hope that helps.
You could use Redisson it has built-in Redis based scheduler and works with Json, Kryo, msgpack and many other codecs. Provides most easier api for Redis power.
I am binding a JSON response to my class using Jackson. Everything works great except when there are more fields in my JSON response than my class defines. I want Jackson to ignore the fields that do not exist in my JSON response. This is due to compatability for future versions. If I add a new field I do not want previous versions of my client to crash.
Ideas?
ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
PromoResponse promoResponse = mapper.readValue(r, PromoResponse.class);
You can put the #JsonIgnoreProperties(ignoreUnknown=true) annotation on your PromoResponse class.
I believe you would want to do something like this after you declare your mapper object:
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-Dan