Работает ли _locateMapperViaProvider при использовании Aries Felix, Aries Blueprint и CXF-RS? - PullRequest
1 голос
/ 17 апреля 2019

Почему аннотация @Provider не работает? (Цель - добавить модуль в синглтон ObjectMapper)

Согласно JavaDocs ,

Конструктор по умолчанию, обычно используется, когда поставщик автоматически настраивается для использования с реализацией JAX-RS.

при вызове JacksonJsonProvider с пустым конструктором,

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

ObjectMapper просто установлен в нуль. BASIC_ANNOTATIONS, вероятно, содержит @Provider.

Каким-то образом должна быть возможность установить ObjectMapper после того, как Blueprint инициализирует классы в память.

Так что у меня есть два варианта:

  • вставить что-то в конструктор JacksonJsonProvider, чтобы у ObjectMapper были все зарегистрированные модули при инициализации.
  • «разрешить» экземпляр ObjectMapper JacksonJsonProvider и зарегистрировать модули вскоре после инициализации.

Похоже,

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">

Мой класс @Provider

@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;
    }
}

Мой сериализатор

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();
        }
    }
}

1 Ответ

0 голосов
/ 19 апреля 2019

Кажется, ответ: "Нет, сэр".

Аннотация @Provider не работает, насколько я могу судить.Поставщики должны быть введены / зарегистрированы в CXF во время инициализации.Я приветствую альтернативный ответ.

<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">
...