Apache CXF - Установить HTTP-заголовок
Мне нужно установить некоторые HTTP-заголовки в клиенте Apache CXF:
Я попробовал это через Interceptor:
public class HttpHeaderInterceptor extends AbstractPhaseInterceptor<Message> {
private String userId;
private String xAuthorizeRoles;
private String host;
public HttpHeaderInterceptor() {
super(Phase.POST_PROTOCOL);
}
@Override
public void handleMessage(Message message) throws Fault {
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
try {
System.out.println("HttpHeaderInterceptor Host: " + host + " UserId: " + userId + " X-AUTHORIZE-roles: " + xAuthorizeRoles);
headers.put("Host", Collections.singletonList(host));
headers.put("UserId", Collections.singletonList(userId));
headers.put("X-AUTHORIZE-roles", Collections.singletonList(xAuthorizeRoles));
} catch (Exception ce) {
throw new Fault(ce);
}
}
public void setUserId(String userId) {
this.userId = userId;
}
public void setxAuthorizeRoles(String xAuthorizeRoles) {
this.xAuthorizeRoles = xAuthorizeRoles;
}
public void setHost(String host) {
this.host = host;
}
}
в моем динамическом классе клиента используется метод:
public void setHttHeaderInterceptor(String userId, String xAuthorizeRoles){
Client cxfClient = ClientProxy.getClient(this.abgWebServicePort);
HttpHeaderInterceptor httpHeaderInterceptor = new HttpHeaderInterceptor();
httpHeaderInterceptor.setHost("example.org");
httpHeaderInterceptor.setUserId(userId);
httpHeaderInterceptor.setxAuthorizeRoles(xAuthorizeRoles);
cxfClient.getOutInterceptors().add(httpHeaderInterceptor);
}
вызывается перед вызовом удаленной службы:
Для каждого вызова userId и xAuthorizeRoles должны меняться, но когда я проверяю вызовы через tcpdump, все вызовы имеют одинаковые значения в полях заголовка.
Любые идеи?
Ответы
Ответ 1
Я решил свою проблему:
добавление перехватчика через конфигурацию xml:
<jaxws:client id="clientBean" serviceClass="org.example.service.ServicePortType"
address="example.org/src/service/ServicePort">
<jaxws:outInterceptors>
<bean class="org.example.interceptor.HttpHeaderInterceptor"/>
</jaxws:outInterceptors>
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:client>
в классе клиента я изменил setHttpHeaderInterceptor на
public void setHttpHeaderInterceptor(String userId, String xAuthorizeRoles){
Client cxfClient = ClientProxy.getClient(this.servicePort);
cxfClient.getRequestContext().put("HTTP_HEADER_HOST", "example.org");
cxfClient.getRequestContext().put("HTTP_HEADER_USER_ID", userId);
cxfClient.getRequestContext().put("HTTP_HEADER_X_AUTHORIZE-ROLES", xAuthorizeRoles);
}
класс перехватчика
@Override
public void handleMessage(Message message) throws Fault {
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
try {
headers.put("Host", Collections.singletonList(message.get("HTTP_HEADER_HOST")));
headers.put("KD_NR", Collections.singletonList(message.get("HTTP_HEADER_KD_NR")));
headers.put("X-AUTHORIZE-roles", Collections.singletonList(message.get("HTTP_HEADER_X_AUTHORIZE-ROLES")));
} catch (Exception ce) {
throw new Fault(ce);
}
}
и теперь это работает.
При таком подходе я могу установить поля HTTP-заголовка во время выполнения.
Ответ 2
Вы должны были использовать: Phase.POST_LOGICAL
вместо Phase.POST
. Это сработало для меня
Ответ 3
Вот фрагмент кода для копирования пользовательского HTTP-заголовка (из запроса) в ответ в одном перехватчике CXF.
public void handleMessage(SoapMessage message) throws Fault {
// Get request HTTP headers
Map<String, List<String>> inHeaders = (Map<String, List<String>>) message.getExchange().getInMessage().get(Message.PROTOCOL_HEADERS);
// Get response HTTP headers
Map<String, List<String>> outHeaders = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS);
if (outHeaders == null) {
outHeaders = new HashMap<>();
message.put(Message.PROTOCOL_HEADERS, outHeaders);
}
// Copy Custom HTTP header on the response
outHeaders.put("myCustomHTTPHeader", inHeaders.get("myCustomHTTPHeader"));
}
Ответ 4
Если требуется установить стандартный HTTP-заголовок, то это можно сделать и с помощью http-кабеля.
<http-conf:conduit
name="*.http-conduit">
<http-conf:client AllowChunking="false" AcceptEncoding="gzip,deflate" Connection="Keep-Alive"
Host="myhost.com"/>
</http-conf:conduit>