Skip to content

Support for BCP 47 java.util.Locale serialization/deserialization #3259

@abrav9595

Description

@abrav9595

Describe the bug

Locale with BCP 47 extensions are not serialized / de-serialized as expected using ObjectMapper.

Version information

Which Jackson version(s) was this for?
All Jackson versions.

To Reproduce

If you have a way to reproduce this with:

Brief code sample/snippet: include here in pre-formatted/code section

Locale locale = Locale.forLanguageTag("en-US-x-debug");
// ^^^ above locale will have x-debug as extensions
// This locale is a BCP 47 compliant locale.

ObjectMapper objectMapper = new ObjectMapper();

String serializedLocale = objectMapper.writeValueAsString(locale);
// ^^^ Will be en_US-#x-debug. Conforms to toString() method of Locale.
// This is not correct. There is a rogue # is added before extensions. 

Locale deserializedLocale = objectMapper.readValue(serializedLocale, Locale.class); 
// ^^^ Due to the rogue # before the extensions, when we de-serialize it, the extensions get added as a Variant instead of extensions.

Longer example stored somewhere else (diff repo, snippet), add a link

N/A. Reproducible with the above piece of code.

Textual explanation:

  • forLanguageTag locale is used to create a locale object from a BCP 47 compliant locale string. The x-debug gets added as extensions in the Locale.
  • However, when we use ObjectMapper to serialize the string, objectMapper uses toString() method of locale to convert it to String.
  • As Per Locale Javadocs, for BCP 47 locales, we must be using toLanguageTag() and forLanguageTag() instead to convert to / from String.
  • Due to this, when we try to de-serialize this malformed Locale, the x-debug gets added as a Variant instead of extensions, which is not expected.

Expected behavior

  • BCP 47 extensions should be added as extensions and not as Variants when serializing and de-serializing.

Additional Details

  • Due to this drawback, we are forced to write our own serializer / de-serializer. It would be nice if ObjectMapper provides us a Module which does this for us.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions