web-dev-qa-db-fra.com

Apache CXF - Définir l'en-tête HTTP

Je dois définir des champs d'en-tête http dans un client Apache CXF:

Je l'ai essayé via 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;
    }
}

dans ma classe de client dynamique, la méthode:

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

est appelé avant que j'appelle le service distant:

Pour chaque appel, l'ID utilisateur et les xAuthorizeRoles devraient varier, mais lorsque j'inspecte via des appels via tcpdump, tous les appels ont les mêmes valeurs dans les champs d'en-tête.

Des idées?

15
Alex

J'ai résolu mon problème:

ajout de l'intercepteur via la configuration 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>

dans la classe client, j'ai modifié setHttpHeaderInterceptor en

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

la classe d'intercepteur 

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

et maintenant ça marche.

Avec cette approche, je peux définir des champs d'en-tête HTTP lors de l'exécution.

14
Alex

Vous devriez avoir utilisé: Phase.POST_LOGICAL au lieu de Phase.POST. Cela a fonctionné pour moi

1
NVN

Voici un extrait de code permettant de copier un en-tête HTTP personnalisé (à partir de la demande) sur la réponse dans un seul intercepteur CXF out. 

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"));
}
1
Floppyr

Si nécessaire pour définir un en-tête HTTP standard, vous pouvez également utiliser un conduit http.

<http-conf:conduit
        name="*.http-conduit">
<http-conf:client AllowChunking="false" AcceptEncoding="gzip,deflate" Connection="Keep-Alive"
 Host="myhost.com"/>
</http-conf:conduit>
0