Spring/Jackson Mapping Inner JSON Objects - java

I have a RESTful web service that provides JSON that I am consuming. I am using Spring 3.2 and Spring's MappingJacksonHttpMessageConverter. My JSON looks like this:
{
"Daives": {
"Daive": {},
"Daive": {},
"Daive": {},
"Daive": {}
}
}
Now everything I have read seems to indicate that this JSON should be refactored to an array of JSON Daives. However, this is valid JSON so I want to make sure that I am thinking correctly before going back to the service provider to ask for changes. In the format above, I would have to know ahead of time how many Daives there are going to be such that my DTO accounted for them. The handy dandy Jackson mapper isn't going work with this kind of JSON setup. If the JSON was altered to provide and Array of JSON Daives, I could use a List to dynamically map them using Spring/Jackson.
Am I correct? Thanks :)

According to this thread, the JSON spec itself does not forbid multiple fields with the same name (in your case, multiple fields named "Daive" in the object "Daives").
However, most parsers will either return an error or ignore any value but the last one. As you said, putting these values into an array seems much more sensible; and indeed, you'll be able to map this array to a List with Jackson.

Related

Easier way of converting Json to Java (Jackson)

I am receiving massive json objects from a service and so far i've been creating POJOs to match the json that comes in.
However, this is getting far too tedious as with every different service I hit I have to build 15-20 new model classes to represent the new service i'm hitting.
In short, what i'm looking for is a way to get a value I need from a neested object in the json as below (sorry for format):
random1 {
random2 {
arrayOfRandoms
}
random3 {
random4 {
random5 {
someValueIWant
}
}
}
}
so in this case I want random5s someValueIWant object. I want to get it without creating the models for random1/3/4/5 as i've been doing this whole time.
I should mention that I use Jacksons ObjectMapper to turn the json into java objects.
Hope this makes sense.
You could experiment with this online pojo generator:
http://www.jsonschema2pojo.org/
It will generate java classes from plain json (or json schema) and even add jackson annotations.
Make sure you check "Allow additional properties".
It requires valid json as input, so don't forget double quotes around fields names and values
If you find yourself doing that often, there's even scriptable versions and maven plugins.

Deserializing selected property names only (Jackson)

Let's say we have following JSON,
{
"id": "imgsId1",
"type": "Fruits",
"name": "Tropical",
"image":
{
"url": "images/img1.jpg",
"width": 300,
"height": 300
},
"thumbnail":
{
"url": "images/thumbnails/img11.jpg",
"width": 50,
"height": 50
}
}
And in Java Class, we have all fields matching with above JSON.
Each time list of fields to be Deserialized depends on customer who sends the information.
For example for customer 1, we want to only read back following values, (and skip other properties even if provided in JSON)
String[] propertiesToFilter1 = {"type","image.url"};
For example for customer 2, we want to read back following values, (and skip other properties even if provided in JSON)
String[] propertiesToFilter2 = {"type","image.url", "image.width"};
When Deserializing JSON using Jackson, is it possible to provide above array which includes which fields need to be Deserialized,
ImageInfo obj1 = (ImageInfo)objectMapper.readValue(jsonStr, ImageInfo.class);
Update:
On researching on net, i saw that one of the options could be via using
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("filterName1",
SimpleBeanPropertyFilter.serializeAllExcept(propertiesToFilter1));
objectMapper.setFilters(filterProvider);
But i think this is good, if we want to keep reusing the same "filterName1" for multiple customers.
In this scenario, it's little bit different because, we customize list of fields each customer can update. So each customer has different list of JSON fields they can update in different classes.
If we start defining different filter names for each customer, it will be a long list, and lookup will have performance impact.
So was looking for solution, where i can check list of fields allowed to be processed at runtime, when constructing back object using objectMapper.readValue() method.
Update 2 (Apr 25 2016):
Going through other Jackson questions, saw a similar question here,
Jackson Dynamic filtering of properties during deserialization
Using the approach listed below by creating custom "static ObjectMapper", the issue with this approach is we running Reflection API multiple times.
First time Jackson parser is populating all fields using
Reflection API when Deserializing JSON to Java Object
Second time, since we can't take all fields that were populated by
Jackson parser, for populate data into another object, we again need to run through Reflection API to populate another object.
This could result in lot of overhead.
Using the approach defined in above link provided, i think using "BeanDeserializerModifier" seems to be best approach. Now the question is, since we are also using Factory based approach to initialize ObjectMapper, we don't want to hard code all arrays for different customers.
Wanted to check if it's possible to provide the String[] array with list of Properties to be considered at runtime to "BeanDeserializerModifier"?
something similar to,
String[] propertiesToFilter2 = {"type","image.url", "image.width"};
BeanDeserializerModifier curBeanDeserializerModifier =
getBeanDeserializerModifierInstance();
curBeanDeserializerModifier.setPropertiesToConsider(propertiesToFilter2);
Thanks
use #JsonIgnoreProperties with configure parameters
http://www.programcreek.com/java-api-examples/index.php?api=com.fasterxml.jackson.annotation.JsonIgnoreProperties
I am not sure if there is a possibility to configure the deserialization dynamically with annotations.
I would suggest to create a class with a static ObjectMapper. In this class you can create different implementations of deserialization. The business logic of your application should then decide which implementation should be used for which customer. Inside your different implementations you are able to configure the ObjectMapper like you do it with annotations.
A second solution can be to deserialize the full json for every customer and let the business logic decide which fields/objects of the Pojo is used. This needs also an implementation in your application.
The benefit of the implementation of the configuration in the business logic is that you will have cleaner code and one place where your configuration is done for every customer.
static ObjectMapper information

What's the fastest way to build a JSON string in java?

I'm working with JSON on the server for the first time. I'm trying to create an object that looks like this:
{
columnData : {
column1 : {"foo": "bar", "value" : 1 },
},
rowData : {
row1 : {"type" : "integer", "value" : 1},
}
}
Essentially, it's a two-level JSON object in which I've got all objects on the top level. Everything on the second level will be a string, and integer, or a float. I've found several ways I could go about creating this JSON string:
Build the string directly
I can go through one line at a time and build up a giant string. This seems unwieldy.
Use gson
I can build a map (or class?) that has the structure of the JSON I want, and then use gson to convert to a JSON string.
Use JsonObject
This would work like this question. I just found that example, and I like how simple working with JSON looks in it, but I'm not sure if it's a better way to go than the other options.
I'm pretty new with Java, so I'm not really sure what the performance tradeoffs of these methods are. I do know that I'll potentially be calling this method lots of times very quickly to load data into a client as the user scrolls a table in a webapp, so I'd like everything to be as fast as possible. What's the quickest way to go about building the JSON string that I'll then be sending back to the client?
Depends on what "fastest" means. Fast to develop or fast in terms of performance.
Fastest on dev is to use a library to serialize existing data structures directly to JSON. Use the following library.
http://flexjson.sourceforge.net
Performance wise comparisons it matches Jackson and beats in some cases and destroys gson. But that means you would be serializing your data structures directly rather than mapping them by hand with JSONObject or something like that.
You may be able to get a faster transaction / sec by using JSONObject by hand and mapping your data structures to it. You might get better performance, but then you might not because you have to new up JSONObject and convert the data to it. Then allow JSONObject to render. Can you write hand written code better than a serializing library? Maybe, maybe not.

How do I print json structure for a multi-level json using java

I am very new to JSON and am not sure if the term "multi-level" json is correct. If not, please help correct it.
I have been tasked with printing the request and response structure of a given rest service. I have the api.json which refers to a host of json objects, which in turn refer to other json objects and so on...
Please note that I am interested in printing the structure and not the contents of the request and response.
I know that I can go ahead and do a recursive read of the files and get this done. But that does not seem right.
Can someone please provide some pointers for the same?
There is a general misconception about JSON. JSON is a format to represent a complex data structure as a string. That's it. JSON itself doesn't know anything about structure - it's really just a string. What you can do is parse the JSON string to get JavaScript objects (i.e. numbers, strings, arrays and things of type object).
This means that you can't really learn enough about the structure of the rest service by looking at JSON strings it accepts or sends. You need to look at the documentation or the internal objects which the service uses to parse the JSON instead.
Example:
{"foo":"bar"}
That tells you that the REST service accepts a JavaScript object and one of the possible parameters. But it doesn't tell you about the other 50 parameters.
If you only have the JSON, then you can use a parsing library to turn that into something that you can print. But unless you want pretty printing (indent and such), that's the same as printing the JSON string itself, so you don't gain anything.

Converter from Json into groovy CODE?

It's a kind of odd question for an odd situation. I have a large JSON structure which I would like to represent in running groovy code. I need groovy objects that mirror the same structure as the JSON objects.
As to be expected a web search mostly returns results with groovy/json runtime conversion stuff, but nothing about things that output groovy code.
You might think this lazy but really it is a massive JSON structure! A converter would save days!
You can use Groovy's own JsonSlurper to parse JSON objects:
import groovy.json.*
def json = '{"name":"john", "surname":"doe", "languages": ["groovy", "python"]}'
def obj = new JsonSlurper().parseText(json)
assert obj.name == "john"
assert obj.surname == "doe"
assert obj.languages.containsAll("python", "groovy")
Of course the class is untyped: it's only known at runtime. If you want it to be typed, you can write a code which writes the code based on an example (since a json schema may be rare).
EDIT: if you want to generate the model classes code, you can try JSONGen, which "parses JSON to create client side source files to model the JSON data structure". I'm not aware of a solution for Groovy, but since java-groovy integrations is seamless, it shall work fine.
If you want a Groovy representation of your JSON, you can get that via the built-in JsonSlurper. This will give you Java Maps and Lists of data you can work with.
You can populate more specific, custom objects you've written to represent your JSON entities using the (3rd party) Jackson's data binding functionality (see this question as well).
Try using a JSON parser like this one. According to its documentation you just need to do
JSON.parse
to deserialize the data

Categories

Resources