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