Can I get the equivalent of @JsonAnySetter functionality, outside of the object?

720 views Asked by At

I have this definition in an object that gets deserialized by Jackson:

public class ImportantInterfaceObject {

    @JsonAnySetter
    private Map<String, String> unmapped = new HashMap<String, String>();

    // ... other stuff omitted for clarity ...
}

This works great in allowing the unmapped member to capture any unexpected values in the input to be processed and dealt with according to requirements and best-practices.

However, it pollutes the ImportantInterfaceObject definition with this additional baggage.

Is there a way to accomplish the same effect as @JsonAnySetter but at another level of the Jackson object lifecycle?

For instance,

ObjectMapper objectMapper = new ObjectMapper();

// pseudo-code, this doesn't exist
objectMapper.setAnyHandler((key,value) -> doSomething(...));

// back to normal valid code now
JsonNode json = objectMapper.readTree(input);
1

There are 1 answers

0
pirho On BEST ANSWER

If you just would like to ignore unmapped properties you would make something like:

ObjectMapper om = new ObjectMapper();
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

But I guess you want to enable some handling fot the unknown properties but at the same time keep it hidden from the actual logic of the class.

In that case you could just use inheritance and instead of Map create a method that uses @JsonAnySetter annotation, something like:

public class UnmappedPropertyHandler {
    @JsonAnySetter
    private void handleUnmapped(String name, String value) {
        // do what you need
    }
}

and

public class ImportantInterfaceObject extends UnmappedPropertyHandler {
    // ... any actually mapped stuff
}

You can also declare interface, but if Java8 you cannot then hide the method:

interface IUnmappedPropertyHandler {
    @JsonAnySetter
    default void handleUnmapped(String name, String value) {
    }
}

For Java11 it is possible, like:

interface IUnmappedPropertyHandler {
    @JsonAnySetter
    private void handleUnmapped(String name, String value) {
    }
}