3

I have a pojo that has a field of type CurrencyUnit from the javamoney library. When I marshall this pojo Jackson throws an exception. I remember this exception when I did not define any default constructor. But in this case I can not maintain the CurrencyUnit class since it's coming from a dependency. How can I still make this work?

Exception:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `javax.money.CurrencyUnit` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information\n at 
xetra11
  • 7,671
  • 14
  • 84
  • 159

1 Answers1

5

You should write a custom serialiser/deserialiser for each type from javax.money package you want to use or register already created module. For example: jackson-datatype-money.

You need to add dependency:

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>jackson-datatype-money</artifactId>
    <version>1.3.0</version>
</dependency>

Simple example how to use:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.zalando.jackson.datatype.money.MoneyModule;

import javax.money.CurrencyUnit;
import javax.money.Monetary;

public class JsonMoneyApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.registerModule(new MoneyModule());

        CurrencyUnit cu = Monetary.getCurrency("USD");
        String json = mapper.writeValueAsString(cu);
        System.out.println(json);

        CurrencyUnit unit = mapper.readValue(json, CurrencyUnit.class);
        System.out.println(unit);
    }
}

above code prints:

"USD"
USD
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • is there a way to add this automatically? Spring is using jackson when returning objects of request mapping methods for example. There is no explicit use of `ObjectMapper` – xetra11 Nov 05 '19 at 20:53
  • 1
    @xetra11, try to add this library on classpath and maybe `Spring`'s `ObjectMapper` builder will find and register it automatically. It depends from version of `Spring` and how you set up your app. If it not will be registered automatically take a look on online resources: [Consume & Produce XML](https://stackoverflow.com/questions/58184442/springboot-consume-produce-xml-with-a-custom-serializer-deserializer), [Register a custom Jackson ObjectMapper using Spring Javaconfig](http://www.jworks.nl/2013/08/21/register-a-custom-jackson-objectmapper-using-spring-javaconfig/) – Michał Ziober Nov 05 '19 at 21:08
  • 1
    @xetra11, moreover take a look at [Configuring ObjectMapper in Spring](https://stackoverflow.com/questions/7854030/configuring-objectmapper-in-spring), [Different JSON configuration in a Spring application for REST and Ajax serialization](https://stackoverflow.com/questions/22691765/different-json-configuration-in-a-spring-application-for-rest-and-ajax-serializa), [Spring, Jackson and Customization](https://stackoverflow.com/questions/3591291/spring-jackson-and-customization-e-g-customdeserializer), [custom jackson](http://magicmonster.com/kb/prg/java/spring/webmvc/jackson_custom.html) – Michał Ziober Nov 05 '19 at 21:10