Zoran Simic
Zoran Simic

Reputation: 10333

Serialized JSON with sorted keys, using Jackson

I'm trying to replace a custom JSON (de)serialization in a groovy/grails project with Jackson.

I'm having trouble getting Jackson to output a pretty-printed JSON with keys sorted in a simple 'natural' alphabetic order. I've tried this (and many variations):

mymap = [ ... ] // Some groovy map
def mapper = new ObjectMapper()
mapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true)
def jsonstring = mapper.defaultPrettyPrintingWriter().writeValueAsString(mymap)

But Jackson stubbornly generates a JSON where the keys seem to be in a random order. I've tried changing the type of 'mymap' with a TreeMap, and in that case all keys are properly sorted as expected.

I'm wondering if there is a way to get the keys sorted without changing 'mymap' above to a TreeMap (and recursively all of its map values...).

SORT_PROPERTIES_ALPHABETICALLY seems to be intended to do precisely that, but it's not doing it for some reason. Would you know why that is? Anything I'm doing wrong above?

I've tried with Jackson 1.8.3, 1.8.8 and 1.9.5, same result (random keys).

Upvotes: 24

Views: 17806

Answers (3)

bknopper
bknopper

Reputation: 1243

As stated by @tim_yates, this doesn't work for map keys.

You could use

mapper.configure(SerializationConfig.Feature.ORDER_MAP_ENTRIES_BY_KEYS, true)

With newer version ( >= 2.6.1) the API changed to:

mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

Upvotes: 34

StaxMan
StaxMan

Reputation: 116512

As pointed out, this feature just works for POJOs. However, I think there is a feature request to do the same for Maps, at Jackson Jira; and if not, this sounds like a good addition.

But in the meantime I would second @tim_yates suggestion to use intermediate TreeMap for sorting, serializing that: ordering that Map has will be used as is, so this should work.

Upvotes: 1

tim_yates
tim_yates

Reputation: 171084

The documentation for SORT_PROPERTIES_ALPHABETICALLY explicitly says:

Feature that defines default property serialization order used for POJO fields (note: does not apply to Map serialization!)

So I guess you will need to change your input Map (as you say)

Upvotes: 7

Related Questions