سؤال

Based on other issues that were actually resolved in Jersey 2.6, I suspect this might be a Jersey bug, but I wanted to vet it here first.

The following works as expected:

@Provider
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {

    private ObjectMapper mapper;

    @Value("${json.prettyPrint}")
    private boolean prettyPrint = false;

    public ObjectMapperResolver() {
        mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.configure(SerializationFeature.INDENT_OUTPUT, prettyPrint);
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }

    /**
     * Push Joda de/serializers into the actual mapper
     */
    @PostConstruct
    private void configureJodaSerializers() {
        mapper.registerModule(new JodaModule()
                // Our deserializers are more forgiving
                .addDeserializer(LocalDate.class, new CustomLocalDateDeserializer())
                .addDeserializer(LocalTime.class, new CustomLocalTimeDeserializer())

                 // Custom serializer to avoid HH:mm:ss.SSS (we don't want millis)
                .addSerializer(LocalTime.class, new LocalTimeSerializer()));
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }
}

In all my resources, my Joda date types are properly serialized. However, I wanted to grab the same ObjectMapper to use in a non-Jersey managed context (outside of my resources), so I added @Component to the above class with the intention of auto-wiring it elsewhere. After adding @Component (org.springframework.stereotype.Component), Jersey no longer picks up the ObjectMapper from the resolver and my date serialization goes back to the defaults.

Unless I completely misunderstand the annotations, I don't think giving Spring control of the life-cycle should impede Jersey's ability to pick up my resolver. Additionally worth noting is the fact that when we were on Jersey 1.9, we HAD to have @Component on there or else it would not get picked up. In order to get our upgrade from 1.9 to 2.6 working, I actually had initially removed it, but was hoping to put it back.

From my pom:

  • Java 1.7
  • Jackson 2.3.1
  • Jersey 2.6
  • Joda 2.1
  • Spring 4.0.1-RELEASE
هل كانت مفيدة؟

المحلول

I had a similar issue with a similar setup as your one. While probably there's something wrong in Jersey 2.x Spring integration beahviour, i think you can do the follow:

Declare the object mapper as a Spring bean, so you can inject it via spring where you need it:

@Component
public class ObjectMapperBean extends ObjectMapper {

    public ObjectMapperBean() {
        super();
        // Configuration here...
    }

}

Then you write a Jersey context resolver for it:

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    @Autowired
    private ObjectMapperBean objectMapper;

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return objectMapper;
    }

}

Even if not declared as a component you will get the ObjectMapperBean injected in it.

Hope it helps!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top