Parsing JSON with dynamic type value (string or object) with Jackson ObjectMapper
I'm new to Jackson and I'm having some trouble figuring out the best way to handle processed JSON files that are dynamic in nature. I know I can solve the problem with a streaming or API tree, but that would require a lot of code that won't be easy to maintain. For example, take the following two json files:
{
something: "somethingValue"
somethingelse: "anotherValue"
url: "http://something.com"
}
and
{
something: "somethingValue"
somethingelse: "anotherValue"
url: {
service1: [
"http://something.com",
"https://something.com" ],
service2: [
"http://something2.com",
"https://something2.com" ],
}
}
The default behavior for the first json object after parsing it is to add the url to the service1 and service2 url lists in the "url" subclass. where the second allows you to specify very specific urls for each. I planned to use the data object for the url class as follows:
public class url {
// ideally, I would use the java.net.URL instead of String
public List<String> service1;
public List<String> service2;
// also includes getter/setters using a fluent style
...
}
There would also be some other parent class that would have a parameter for url and other first level json parameters.
What's the best way to handle this in jackson?
source to share
Answer:
After struggling with Jackson to do what I want in a simple and elegant way, I ended up switching to the Gson library for parsing JSON. this allowed me to create a custom deserializer for my class, which was very simple.
An example of what I did can be found here:
http://www.baeldung.com/gson-deserialization-guide
I appreciate the help and guidance with Jackson, however it only made me realize that Jackson was simply not going to meet my needs.
-Stewart
source to share
The second is not valid JSON, it is:
{
"something": "somethingValue",
"somethingelse": "anotherValue",
"url": {
"service1" : [
"http://something.com",
"https://something.com" ],
"service2" : [
"http://something2.com",
"https://something2.com" ]
}
}
You can create / destroy it with class A which looks like this
class A{
String something;
String somethingElse;
B url;
}
class B{
Str service1;
List<String> service2;
}
To achieve anything dynamically no matter what you have to put in the lists, so instead of the solution above, you can do this
class A{
String something;
String somethingElse;
B url;
}
class B{
List<C> services;
}
class C{
List<String> service;
}
source to share
I ended up mixing JsonNode together to get this to work.
public class Foo { @JsonProperty ("something") private String something; @JsonProperty ("somethingelse") private String somethingelse; @JsonProperty ("url") JsonNode url; // getters setters public static Foo parse (String jsonString) { ObjectMapper mapper = new ObjectMapper (); Foo foo = mapper.readValue (jsonString, Foo.class); return foo; } public static boolean validate (Foo foo) { JsonNode url = foo.path ("url"); if (url.isTextual ()) { // this is the first case {"url": "http://something.com"} System.out.println (url.getTextValue ()); } else { // This is the second case } } }
source to share