Заголовок CXF AbstractOutDatabindingInterceptor опущен во время определенных запросов

#java #rest #cxf #jax-rs

#java #остальное #cxf #jax-rs

Вопрос:

В настоящее время я пишу REST API, который использует перехватчик CXF для добавления определенных заголовков к каждому запросу.

Код этого перехватчика:

 public class TestHeaderInterceptor extends AbstractOutDatabindingInterceptor {

    public TestHeaderInterceptor() {
        super(Phase.SEND);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void handleMessage(Message message) {
        MultivaluedMap<String, Object> headers = (MetadataMap<String, Object>) message.get(Message.PROTOCOL_HEADERS);
        if (headers == null) {
            headers = new MetadataMap<String, Object>();
        }
        headers.add("X-Test", "test");
        message.put(Message.PROTOCOL_HEADERS, headers);
    }
}
  

Итак, как вы можете видеть, я добавляю заголовок, вызываемый X-Test со значением test . Когда я использую клиент CXF REST (на основе прокси), я использую следующий код для добавления перехватчика к клиенту:

 Client client = WebClient.client(clientObj);
ClientConfiguration config = WebClient.getConfig(client);
List<Interceptor<? extends Message>> interceptors = new ArrayList<Interceptor<? extends Message>>();
interceptors.add(new TestHeaderInterceptor());
config.setOutInterceptors(interceptors);
  

Мой REST API имеет только 2 действия:

 @GET
@Produces(JSON_UTF8)
@Path("test/{id}")
Test test(@PathParam("id") String id);


@POST
@Produces(JSON_UTF8)
@Path("test2/{type}")
@Consumes(JSON_UTF8)
Test test2(Test obj, @PathParam("type") Type type);
  

test/{id} Метод работает успешно, и он добавляет заголовок (проверено с помощью Wireshark). Однако test2/{type} вызов не добавляет заголовок к запросу.

Самое странное, что при использовании debug явно вызывается код перехватчика, что заставляет меня думать, что каким-то образом Apache CXF пропускает заголовки, которые я добавляю.

Это также причина, по которой я использую Phase.SEND фазу вместо Phase.MARSHALL , просто потому, что я думал, что мои заголовки пропущены где-то в процессе выполнения всех этих этапов. Но даже сейчас заголовки все еще отсутствуют.

Ответ №1:

После некоторой отладки я обнаружил, что цепочка перехватчиков CXF отличается, когда я использую test2 вызов, например:

Цепочка перехватчиков с тестом:

 [2014-06-13 10:49:48,535] - [DEBUG] - [Default Executor-thread-1] - [PhaseInterceptorChain.java:682] - Chain org.apache.cxf.phase.PhaseInterceptorChain@1384d8d1 was modified. Current flow:
  pre-logical [ClientRequestFilterInterceptor]
  prepare-send [MessageSenderInterceptor]
  marshal [TestHeaderInterceptor]
  prepare-send-ending [MessageSenderEndingInterceptor]
  

Цепочка перехватчиков с test2:

 [2014-06-13 10:50:02,205] - [DEBUG] - [Default Executor-thread-1] - [PhaseInterceptorChain.java:682] - Chain org.apache.cxf.phase.PhaseInterceptorChain@69a33de5 was modified. Current flow:
  pre-logical [ClientRequestFilterInterceptor]
  prepare-send [MessageSenderInterceptor]
  write [BodyWriter]
  marshal [TestHeaderInterceptor]
  prepare-send-ending [MessageSenderEndingInterceptor]
  

Как вы можете видеть BodyWriter , на этапе записи есть дополнительный перехватчик. Я полагаю, что при написании тела запроса вы больше не можете получить доступ к заголовкам (потому что тело идет после заголовков).

Итак, исправление состояло в том, чтобы фактически переместить TestHeaderInterceptor в фазу перед BodyWriter , поэтому в моем коде я теперь использую следующий код в своем конструкторе:

 public TestHeaderInterceptor() {
    super(Phase.SETUP);
}