package com.fasterxml.jackson.module.guice; import com.fasterxml.jackson.annotation.JacksonInject; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.module.guice.ObjectMapperModule; import com.google.inject.Binder; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; import com.google.inject.name.Names; import org.junit.Assert; import org.junit.Test; import java.io.IOException; import java.math.BigInteger; public class ObjectMapperModuleTest { @Test public void testJacksonInjectThroughGuice() throws Exception { final Injector injector = Guice.createInjector( new ObjectMapperModule(), new Module() { @Override public void configure(Binder binder) { binder.bind(Integer.class).toInstance(1); // guice based named injection binder.bind(Integer.class).annotatedWith(Names.named("two")).toInstance(2); binder.bind(Integer.class).annotatedWith(Ann.class).toInstance(3); // javax based named injection binder.bind(Integer.class).annotatedWith(Names.named("five")).toInstance(5); // guice based method injection binder.bind(Integer.class).annotatedWith(Names.named("six")).toInstance(6); // javax based method injection binder.bind(Integer.class).annotatedWith(Names.named("seven")).toInstance(7); // test other method injections (need different keys, so use Long binder.bind(Long.class).annotatedWith(Ann.class).toInstance(8L); binder.bind(Long.class).toInstance(9L); } } ); final ObjectMapper mapper = injector.getInstance(ObjectMapper.class); mapper.readValue("{\"four\": 4}", SomeBean.class).verify(); } @Test public void testModulesRegisteredThroughNormalInstantiation() throws Exception { final Injector injector = Guice.createInjector( new ObjectMapperModule().registerModule(new IntegerAsBase16Module()) ); final ObjectMapper mapper = injector.getInstance(ObjectMapper.class); Assert.assertEquals(mapper.writeValueAsString(Integer.valueOf(10)), "\"A\""); } @Test public void testModulesRegisteredThroughInjection() throws Exception { final Injector injector = Guice.createInjector( new ObjectMapperModule().registerModule(IntegerAsBase16Module.class) ); final ObjectMapper mapper = injector.getInstance(ObjectMapper.class); Assert.assertEquals(mapper.writeValueAsString(Integer.valueOf(10)), "\"A\""); } @Test public void testModulesRegisteredThroughInjectionWithAnnotation() throws Exception { final Injector injector = Guice.createInjector( new ObjectMapperModule().registerModule(IntegerAsBase16Module.class, Ann.class), new Module() { @Override public void configure(Binder binder) { binder.bind(IntegerAsBase16Module.class).annotatedWith(Ann.class).to(IntegerAsBase16Module.class); } } ); final ObjectMapper mapper = injector.getInstance(ObjectMapper.class); Assert.assertEquals(mapper.writeValueAsString(Integer.valueOf(10)), "\"A\""); } @Test public void testModulesRegisteredThroughInjectionWithNameAnnotation() throws Exception { final Injector injector = Guice.createInjector( new ObjectMapperModule().registerModule(IntegerAsBase16Module.class, Names.named("billy")), new Module() { @Override public void configure(Binder binder) { binder.bind(IntegerAsBase16Module.class) .annotatedWith(Names.named("billy")) .to(IntegerAsBase16Module.class); } } ); final ObjectMapper mapper = injector.getInstance(ObjectMapper.class); Assert.assertEquals(mapper.writeValueAsString(Integer.valueOf(10)), "\"A\""); } @Test public void testModulesRegisteredThroughInjectionWithKey() throws Exception { final Injector injector = Guice.createInjector( new ObjectMapperModule().registerModule(Key.get(IntegerAsBase16Module.class)) ); final ObjectMapper mapper = injector.getInstance(ObjectMapper.class); Assert.assertEquals(mapper.writeValueAsString(Integer.valueOf(10)), "\"A\""); } private static class SomeBean { @JacksonInject private int one; @JacksonInject @com.google.inject.name.Named("two") private int two; @JacksonInject @Ann private int three; @JsonProperty private int four; @JacksonInject @javax.inject.Named("five") private int five; // Those will be injected by methods private int six; private int seven; private long eight; private long nine; @JacksonInject private void injectSix(@com.google.inject.name.Named("six") int s) { this.six = s; } @JacksonInject private void injectSeven(@javax.inject.Named("seven") int s) { this.seven = s; } @JacksonInject private void injectEight(@Ann long e) { this.eight = e; } @JacksonInject private void injectNine(long n) { this.nine = n; } public boolean verify() { Assert.assertEquals(1, one); Assert.assertEquals(2, two); Assert.assertEquals(3, three); Assert.assertEquals(4, four); Assert.assertEquals(5, five); Assert.assertEquals(6, six); Assert.assertEquals(7, seven); Assert.assertEquals(8, eight); Assert.assertEquals(9, nine); return true; } } @SuppressWarnings("serial") static class IntegerAsBase16Module extends SimpleModule { public IntegerAsBase16Module() { super("IntegerAsBase16"); addSerializer( Integer.class, new JsonSerializer<Integer>() { @Override public void serialize( Integer integer, JsonGenerator jsonGenerator, SerializerProvider serializerProvider ) throws IOException, JsonProcessingException { jsonGenerator.writeString(new BigInteger(String.valueOf(integer)).toString(16).toUpperCase()); } } ); } } }