3

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

Community
  • 1
  • 1
mike39
  • 29
  • 5
  • How do you know for which customer you have to deserialize stuff and when not? – Patrick Apr 22 '16 at 08:12
  • This JSON file could be received either via Web (Form POST) or via FTP. For all customers we use the same Java class file. – mike39 Apr 22 '16 at 09:25

2 Answers2

0

use @JsonIgnoreProperties with configure parameters

http://www.programcreek.com/java-api-examples/index.php?api=com.fasterxml.jackson.annotation.JsonIgnoreProperties

EL missaoui habib
  • 1,075
  • 1
  • 14
  • 24
  • Thanks for the response. @JsonIgnoreProperties({"pw", "email", "name", "devices", "lastModified", "created"}) would work if i want to skip considering these fields for files from all Customers. **The scenario here is for different customers we want to customize which fields we want to consider**. – mike39 Apr 22 '16 at 10:32
  • there are a difference between the different client in input data or no – EL missaoui habib Apr 22 '16 at 12:12
0

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

Community
  • 1
  • 1
Patrick
  • 12,336
  • 15
  • 73
  • 115
  • Please check my updated comments. This will have performance impact, since we need to run through Java Reflection API multiple times. – mike39 Apr 25 '16 at 19:21
  • @mike39 at the end you have to register the `BeanDeserializerModifier` in your `objectMapper` for using it. Or I am wrong? – Patrick Apr 28 '16 at 05:55