jackson-datatype-money

by zalando

Extension module to properly support datatypes of javax.money

142 Stars 28 Forks Last release: about 2 months ago (1.2.0) MIT License 508 Commits 21 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

Jackson Datatype Money

Stability: Sustained Build Status Coverage Status Code Quality Javadoc Release Maven Central License

Jackson Datatype Money is a Jackson module to support JSON serialization and deserialization of JavaMoney data types. It fills a niche, in that it integrates JavaMoney and Jackson so that they work seamlessly together, without requiring additional developer effort. In doing so, it aims to perform a small but repetitive task — once and for all.

This library reflects our API preferences for representing monetary amounts in JSON:

{
  "amount": 29.95,
  "currency": "EUR"
}

Features

  • enables you to express monetary amounts in JSON
  • can be used in a REST APIs
  • customized field names
  • localization of formatted monetary amounts
  • allows you to implement RESTful API endpoints that format monetary amounts based on the Accept-Language header
  • is unique and flexible

Dependencies

  • Java 8 or higher
  • Any build tool using Maven Central, or direct download
  • Jackson
  • JavaMoney

Installation

Add the following dependency to your project:

    org.zalando
    jackson-datatype-money
    ${jackson-datatype-money.version}

For ultimate flexibility, this module is compatible with the official version as well as the backport of JavaMoney. The actual version will be selected by a profile based on the current JDK version.

Configuration

Register the module with your

ObjectMapper
:
ObjectMapper mapper = new ObjectMapper()
    .registerModule(new MoneyModule());

Alternatively, you can use the SPI capabilities:

ObjectMapper mapper = new ObjectMapper()
    .findAndRegisterModules();

Serialization

For serialization this module currently supports

javax.money.MonetaryAmount
and will, by default, serialize it as:

{
  "amount": 99.95,
  "currency": "EUR"
}

To serialize number as a JSON string, you have to configure the quoted decimal number value serializer:

ObjectMapper mapper = new ObjectMapper()
    .registerModule(new MoneyModule().withQuotedDecimalNumbers());
{
  "amount": "99.95",
  "currency": "EUR"
}

Formatting

A special feature for serializing monetary amounts is formatting, which is disabled by default. To enable it, you have to either enable default formatting:

ObjectMapper mapper = new ObjectMapper()
    .registerModule(new MoneyModule().withDefaultFormatting());

... or pass in a

MonetaryAmountFormatFactory
implementation to the
MoneyModule
:
ObjectMapper mapper = new ObjectMapper()
    .registerModule(new MoneyModule()
        .withFormatting(new CustomMonetaryAmountFormatFactory()));

The default formatting delegates directly to

MonetaryFormats.getAmountFormat(Locale, String...)
.

Formatting only affects the serialization and can be customized based on the current locale, as defined by the

SerializationConfig
. This allows to implement RESTful API endpoints that format monetary amounts based on the

Accept-Language
header.

The first example serializes a monetary amount using the

de_DE
locale:
ObjectWriter writer = mapper.writer().with(Locale.GERMANY);
writer.writeValueAsString(Money.of(29.95, "EUR"));
{
  "amount": 29.95,
  "currency": "EUR",
  "formatted": "29,95 EUR"
}

The following example uses

en_US
:
ObjectWriter writer = mapper.writer().with(Locale.US);
writer.writeValueAsString(Money.of(29.95, "USD"));
{
  "amount": 29.95,
  "currency": "USD",
  "formatted": "USD29.95"
}

More sophisticated formatting rules can be supported by implementing

MonetaryAmountFormatFactory
directly.

Deserialization

This module will use

org.javamoney.moneta.Money
as an implementation for
javax.money.MonetaryAmount
by default when deserializing money values. If you need a different implementation, you can pass a different
MonetaryAmountFactory
to the
MoneyModule
:
ObjectMapper mapper = new ObjectMapper()
    .registerModule(new MoneyModule()
        .withMonetaryAmount(new CustomMonetaryAmountFactory()));

You can also pass in a method reference:

ObjectMapper mapper = new ObjectMapper()
    .registerModule(new MoneyModule()
        .withMonetaryAmount(FastMoney::of));

Jackson Datatype Money comes with support for all

MonetaryAmount
implementations from Moneta, the reference implementation of JavaMoney:

|

MonetaryAmount
Implementation | Factory | |-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| |
org.javamoney.moneta.FastMoney
|
new MoneyModule().withFastMoney()
| |
org.javamoney.moneta.Money
|
new MoneyModule().withMoney()
| |
org.javamoney.moneta.RoundedMoney
|
new MoneyModule().withRoundedMoney()
| |

Module supports deserialization of amount number from JSON number as well as from JSON string without any special configuration required.

Custom Field Names

As you have seen in the previous examples the

MoneyModule
uses the field names
amount
,
currency
and
formatted
by default. Those names can be overridden if desired:
ObjectMapper mapper = new ObjectMapper()
    .registerModule(new MoneyModule()
        .withAmountFieldName("value")
        .withCurrencyFieldName("unit")
        .withFormattedFieldName("pretty"));

Usage

After registering and configuring the module you're now free to directly use

MonetaryAmount
in your data types:
import javax.money.MonetaryAmount;

public class Product { private String sku; private MonetaryAmount price; ... }

Getting help

If you have questions, concerns, bug reports, etc, please file an issue in this repository's Issue Tracker.

Getting involved

To contribute, simply make a pull request and add a brief description (1-2 sentences) of your addition or change. Please note that we aim to keep this project straightforward and focused. We are not looking to add lots of features; we just want it to keep doing what it does, as well and as powerfully as possible. For more details check the contribution guidelines.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.