vendredi 25 septembre 2020

JsonProperty cannot be read after Custom annotation is used

I have a function which constructs a list of serializable fields per Model class at start up. It does so by searching for @APIField annotation for all the fields in a class and makes a Set<String> of field names. Then it is stored in Map<Class, Set<String >>, creating a static list of class along with it's white listed fields.

Later when I serialize using a custom @JsonFilter, I check if the writer.getName() is a contained in the set of field names and let the writer do the serialization. (it's in the code snippet below)

All this works fine until a @JsonProperty("sname") is used along with @APIField. The serialization happens with field name and not the json property name.

Here is the scenario:

    Class ShowClass {

        @APIField
        @Getter @Setter
        private String firstName;

        @APIField
        @Getter @Setter
        @JsonProperty("ln")
        private String lastname;
   }

Then, JsonFieldsListGenerator function generates Map<Class, Set<String>>, basically for each class, a set of field names that will be serialized. whiteListedFieldsMap in the code snippet is the global variable where I store the whiteListFields.

    Set<String> whiteListFields = new HashSet<>();
    Arrays.stream(clazz.getDeclaredFields()).forEach(field -> {
        if(field.isAnnotationPresent(APIField.class))
        {
            whiteListFields.add(field.getName());
        }
    });
    whiteListedFieldsMap.put(clazz, whiteListFields);

Then My serialization is happening in an overridden serializeAsField method

@Override
public void serializeAsField(Object pojo, JsonGenerator jgen,
        SerializerProvider provider, PropertyWriter writer)
        throws Exception
{
    Set<String> whiteListedFields = getWhiteListedFields(pojo.getClass());

    if(whiteListedFields.contains(writer.getName()))
    {
        writer.serializeAsField(pojo, jgen, provider);
    }

}

The problem is that writer.getName() gives me "ln" for lastName, whereas whiteListedFields contains "lastName".

Expected : {"firstName": "Mike", "ln" : "Gerard"}
Actual   : {"firstName": "Mike", "lastName": "Gerard"}

So, How do I make all the other annotations work properly with my @APIField while maintaining the program flow ?

Yes, one way is to actually save the whitelisted fields with their JsonProperty name. The problem is that if @JsonProperty isn't working, then there are other things that might not be working. So without any duct taping, how do I make sure that all the annotations other than @APIField continue to work (e.g. @JsonValue, @JsonProperty and anything else) ?





Aucun commentaire:

Enregistrer un commentaire