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?

+4


source to share


3 answers


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

0


source


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;
}

      

+1


source


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

        }
    }
}
0


source







All Articles