Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for handling Map.Entry #565

Closed
cowtowncoder opened this issue Sep 29, 2014 · 15 comments
Closed

Add support for handling Map.Entry #565

cowtowncoder opened this issue Sep 29, 2014 · 15 comments

Comments

@cowtowncoder
Copy link
Member

Since use of Map.Entry as type is relatively common for constructs like Iterable<Map.Entry<>> or List<Map.Entry<>>, it'd make sense to support it.
By default, serialization should probably occur as JSON Object with just one entry. Deserializer will need to do bit of verification after entry, to give more meaningful error for possible case of structural mismatch.

A potential added twist is whether to try to optimize more compact forms: specifically, Iterable (or Iterator) of Map.Entry instances could conceivably be simply serialized as JSON Object, instead of JSON Array of single-entry JSON Objects.

One possibility would be to initially support deserialization of such structure (as it should be detectable from JSON Array vs JSON Object difference); and later on maybe add support for serialization as well, using @JsonFormat to indicate difference.

@cowtowncoder
Copy link
Member Author

Let's start with basics tho: simple read/write of Map.Entry as single entry JSON Object.

@cfieber
Copy link

cfieber commented Mar 10, 2015

may be worth calling this out a little more in the 2.5.x release notes - this changes the shape of a serialized collection of Map.Entry from [{'key':'key1', 'value':'value1'}] to {'key1':'value1'}

definitely think the new format is nicer, but we had a legacy api that happened to be emitting the former

@cowtowncoder
Copy link
Member Author

Oh! Apologies for breaking your code. I did not realize serialization was actually working before 2.5, although in hindsight that makes complete change. Had I realized this, I would have added a SerializationFeature. That may not be very useful addition at this point.

I will definitely add a note about this, in (in)compatibility section.

Thank you for reporting this, and once again apologies for causing the breakage. This was definitely not intentional.

@cowtowncoder
Copy link
Member Author

@cfieber Thank you again for pointing it out; I added a note on https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.5 to hopefully help.

@darinmanica
Copy link

Will there be a way to configure 2.5 to render maps in the pre-2.5 manner? What is the recommended upgrade path to 2.5 for a public API (that was using maps) and a substantial user base?

@cowtowncoder
Copy link
Member Author

@darinmanica Rendering of Maps has not changed. What is your specific problem?

@codecracker2014
Copy link

@cowtowncoder i'm facing challenge due to this change as our js api is using key, value attributes. Can i still get earlier serialization of Map.Entry<> with jackson 2.7+ using some configuration?

@cowtowncoder
Copy link
Member Author

@codecracker2014 for serialization, #865 will add alternative to "old" method, but unfortunately it'll only be in 2.9(.0); it would be by using @JsonFormat(shape=Shape.OBJECT) annotation.
Until then custom serializer is the way to go; it should be relatively easy to do that.

@ivascaflavius
Copy link

@cowtowncoder, out of curiosity, do you know by when the 2.9 stable release should be available? I see 2.9-pr3 is already available, and the original release date for 2.9 was originally intended to be April 2017.

@cowtowncoder
Copy link
Member Author

@ivascaflavius Unfortunately I do not know, but fwtw I hope pr3 was the last pre-release. If all went well (... rarely does) I would estimate end of May, but more likely some time in June. The big missing piece that I still want to get done is non-blocking ("async") parsing for json; otherwise almost everything else remaining is optional.

@ivascaflavius
Copy link

@cowtowncoder
Ok, thanks! I have another question.

If we upgrade to version 2.8.x, in order to support backwards compatibility with data that was generated with pre 2.5 for collection of Map.Entry, you mentioned implementing a custom serializer for Map.Entry is the way to go. That is easy to do, and we were able to do that, however what we are struggling with is implementing a deserializer to do the same, specially given that we may have a convoluted object (the value in a Map.Entry may be another map of objects for example etc.).

Can you point us to an easy solution on implementing the deserializer for Map.Entry (by falling back to / reusing other serializers?) or any other way of maintaining the old (pre 2.5) behaviour, if we upgrade to Jackson 2.8.x?

Thanks!

@pedro93
Copy link

pedro93 commented Jul 24, 2017

Hi,

Assuming the current newest version of jackson (2.90-pr4), how could I set an ObjectMapper object with this serialization/deserialization property to allow backwards-compatibility with 2.4.4?

@cowtowncoder
Copy link
Member Author

@pedro93 You can use:

    @JsonFormat(shape=JsonFormat.Shape.OBJECT)

annotation on property, to serialize "as POJO" (i.e. with 2 fields); and:

@JsonFormat(shape=JsonFormat.Shape.NATURAL)

to serialize using new compact notation.

And to set this as the default, you should be able to use:

        mapper.configOverride(Map.Entry.class)
            .setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.OBJECT)

as "per-type config override".

@rlubke
Copy link

rlubke commented Oct 6, 2017

@cowtowncoder

Sorry to pile on here. We're looking to control the wire format of our custom Map.Entry class.
I've set:

mapper.configOverride(Map.Entry.class)
.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.OBJECT)

Per your instructions, but it doesn't seem to work.

We can't, or rather would like to avoid annotating the custom Map.Entry implementation to maintain
separate between the serialization layer and the object layer as we have several different serializers.
We also can't reference the concrete type from the serialization module.

Using Jackson 2.9.1.

Any thoughts?

@cowtowncoder
Copy link
Member Author

@rlubke Could you please file a separate issue, with a link back to this one, with simple reproduction (just to make sure I know exact config).

As to work-around, custom serializer is probably your best bet for time being.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants