cxfapache-felixblueprint-osgi

Does _locateMapperViaProvider work when using Aries Felix, Aries Blueprint, and CXF-RS?


Why is the @Provider annotation not working? (Goal is to append a module to an ObjectMapper singleton)

According to JavaDocs,

Default constructor, usually used when provider is automatically configured to be used with JAX-RS implementation.

when calling JacksonJsonProvider with an empty constructor,

public JacksonJsonProvider() {
        this((ObjectMapper)null, BASIC_ANNOTATIONS);
    }

The ObjectMapper is just set to null. BASIC_ANNOTATIONS probably contains @Provider.

Somehow it must be possible to set the ObjectMapper up after Blueprint has initialized the classes into memory.

So I have two options:

It looks like

protected ObjectMapper _locateMapperViaProvider

Blueprint

<cxf:rsServer id="cxfConsumer" address="/" serviceClass="com.domain.MyServiceInterface">
     <cxf:providers>
         <ref component-id="jsonProvider"/>
    </cxf:providers>
 </cxf:rsServer>
 <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">

My @Provider class

@Provider
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class JacksonObjectMapperProvider implements ContextResolver<ObjectMapper> {

    final ObjectMapper defaultObjectMapper;

    public JacksonObjectMapperProvider() {
        this.defaultObjectMapper = makeObjectMapper();
    }

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

    private static ObjectMapper makeObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new MyObjectSerializerModule());
        return mapper;
    }
}

My serializer

public class MyObjectSerializerModule extends SimpleModule {

    public MyObjectSerializerModule() {
        super("ObjectIdSerializerModule", new Version(1, 0, 0, "alpha"));
        this.addSerializer(MyObject.class, new MyObjectSerializer());
    }

    public class MyObjectSerializer extends JsonSerializer<Location> {

        @Override
        public void serialize(MyObject value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                throws IOException {

            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField("id", value.getId());
            jsonGenerator.writeEndObject();
        }
    }
}

Solution

  • It seems the answer is, "No sir".

    The @Provider annotation does not work as far as I can tell. The providers must be injected/registered with CXF during initialization. I welcome an alternative answer.

    <cxf:rsServer id="cxfConsumer" address="/" serviceClass="com.domain.MyServiceInterface">
         <cxf:providers>
             <ref component-id="jsonProvider"/>
             <ref component-id="JacksonObjectMapperContextProvider"/>
        </cxf:providers>
     </cxf:rsServer>
     <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
    <bean id="jsonProvider" class="JacksonObjectMapperContextProvider">