Serialized JSON with sorted keys, using Jackson

12,925

Solution 1

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);

Solution 2

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)

Solution 3

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.

Share:
12,925

Related videos on Youtube

Zoran Simic
Author by

Zoran Simic

Eiffel programmer. Making iphone apps as a hobby

Updated on June 04, 2022

Comments

  • Zoran Simic
    Zoran Simic almost 2 years

    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).

  • Zoran Simic
    Zoran Simic about 12 years
    Good point, I missed that. Looks like I may have to forget the nice elegant way of just setting a serialization preference.
  • tim_yates
    tim_yates about 12 years
    You should be able to do: def jsonstring = mapper.defaultPrettyPrintingWriter().writeValueAsString(myma‌​p as TreeMap) can't you?
  • Zoran Simic
    Zoran Simic about 12 years
    No that doesn't help. The implementation of 'mymap' isn't TreeMap. And even if it was, I would have to make sure that all the other map values in 'mymap' are also TreeMap, and that's where it gets very tricky.
  • Mišo
    Mišo about 8 years
    For me JSON_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES‌​_BY_KEYS, true) works great and this answer was very helpful :)
  • bknopper
    bknopper about 8 years
    Good to hear! :-) Can save a lot of time ;-)
  • Tom
    Tom almost 8 years
    Thanks! In v2.6.1 it seems to have been moved to a different package. This worked for me: mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_K‌​EYS, true);
  • Matt Klein
    Matt Klein almost 7 years
    MAKE SURE TO LOOK AT NEXT ANSWER - You don't need to change your input map.
  • Mikael Olsson
    Mikael Olsson over 6 years
    For me it's writerWithDefaultPrettyPrinter() that breaks the sorting. Without pretty printer SORT_PROPERTIES_ALPHABETICALLY works perfectly