Open motlin opened 4 months ago
From the description, it seems like the current implementation does not handle the concept of "default"
across...
@JsonTypeInfo
), and @JsonInclude
Question may start with... should it? The suggested feauture seems quite intuitive tho.
This is unfortunately not doable: Type Ids (and Object Ids) are -- for the most part -- metadata, not data, and @JsonInclude
and other mechanism only relate to data ("real" properties). So none of mechanisms defined will change inclusion of Type Ids; and I don't have any plans to change that.
But let's see if this particular problem could be solved using other mechanisms.
My first question here is that of why is polymorphic handling enabled? Is that necessary? If no Type Ids are needed for serialization, there are (at least) 2 ways this could be done without changing POJO definitions:
@JsonTypeInfo
with @JsonTypeInfo(use = Id.NONE)
at level(s) necessary (base class)@JsonTypeInfo
in JacksonAnnotationIntrospector
and blocking discovery (I forget specific method but it should be easy to find from class)Some more context about what I'm trying to do. I'm working on Dropwizard configuration logging inside a library of Dropwizard add-ons that I wrote called Liftwizard.
Dropwizard ships with a way to deserialize config.yml into a Configuration object, including polymorphic configuration. The configuration objects include default values set up in constructors.
In order to know what configuration fields are even available to be changed, I find it helpful to serialize the config back to json and log it. For example, if I take a default Configuration object and serialize it...
Configuration plainConfiguration = new Configuration();
String plainConfigurationString = objectMapper.writeValueAsString(plainConfiguration);
LOGGER.info("Inferred Dropwizard configuration:\n{}", plainConfigurationString);
... I get a bunch of json.
{
"logging": {
"type": "default",
"level": "INFO",
"loggers": {},
"appenders": [
{
"type": "console",
"threshold": "ALL",
"timeZone": "UTC",
"queueSize": 256,
"discardingThreshold": -1,
"includeCallerData": false,
"filterFactories": [],
"target": "STDOUT"
}
]
},
"metrics": {
"frequency": "1 minute",
"reporters": [],
"reportOnStop": false
},
"server": {
"type": "default",
"maxThreads": 1024,
"minThreads": 8,
...
... and a lot more, 143 lines total. It's sort of easier to work with this json than look up available properties in the configuration reference.
After making lots of edits to the config.yml, I'd like to see which parts I can now remove because they are defaults. I want to echo back a "minimized" configuration object.
As a test, I can try to serialize new Configuration()
again and see how small the MixIn workaround can get to the empty object {}
.
ObjectMapper nonDefaultObjectMapper = objectMapper.copy();
nonDefaultObjectMapper.setMixInResolver(new JsonIncludeNonDefaultMixInResolver());
String configurationString = nonDefaultObjectMapper.writeValueAsString(new Configuration());
LOGGER.info("Dropwizard configuration (minimized):\n{}", configurationString);
The resulting json is much shorter.
{
"logging": {
"type": "default",
"appenders": [
{
"type": "console"
}
]
},
"server": {
"type": "default",
"applicationConnectors": [
{
"type": "http"
}
],
"adminConnectors": [
{
"type": "http",
"port": 8081
}
],
"serverPush": {},
"requestLog": {
"type": "logback-access",
"appenders": [
{
"type": "console"
}
]
},
"gzip": {}
},
"metrics": {},
"admin": {
"healthChecks": {},
"tasks": {}
}
}
There are a few empty objects left, and I think that's because the Java types don't implement equals(). Besides that, everything remaining is polymorphic type information.
One thing that could be conceptually acceptable (and useful) would be to support rule of "do not write Type Id if it is the same as defaultImpl
. But it is quite literally easier said than done.
But if anyone could figure it out (I don't have time to dig deep here but I always try to help those that do!), that could help here I think?
And I have feeling there might actually be an issue filed for this.
EDIT: indeed there is... #644 . Almost 10 years old, vintage issue. :)
Is your feature request related to a problem? Please describe.
I'm trying to serialize a minimized Dropwizard configuration object, excluding any default values, in https://github.com/motlin/liftwizard/pull/2011/files.
The first thing I tried was setting Include.NON_DEFAULT globally, but it's well documented on the annotation itself that it does not work on objects globally, only primitives.
I came up with a decent workaround using mixins.
This works fairly well and excludes most default values. Now when serializing a default configuration object, most of the remaining content comes from default type information set using
JsonTypeInfo
. For example:Describe the solution you'd like
I'd like some way of excluding as many json fields as possible that get serialized on an object created with its default constructor, specifically the default type information from
JsonTypeInfo
'sdefaultImpl
Usage example
String is:
I'd expect the empty object
{}
here.Additional context
No response