使用Spring-WS客户端动态设置自定义HTTP标头

use*_*735 33 java spring spring-ws header http

在使用Spring-WS时,如何在客户端动态设置自定义HTTP头(而不是SOAP头)?

use*_*735 27

public class AddHttpHeaderInterceptor implements ClientInterceptor {

public boolean handleFault(MessageContext messageContext)
        throws WebServiceClientException {
    return true;
}

public boolean handleRequest(MessageContext messageContext)
        throws WebServiceClientException {
     TransportContext context = TransportContextHolder.getTransportContext();
     HttpComponentsConnection connection =(HttpComponentsConnection) context.getConnection();
     connection.addRequestHeader("name", "suman");

    return true;
}

public boolean handleResponse(MessageContext messageContext)
        throws WebServiceClientException {
    return true;
}

}
Run Code Online (Sandbox Code Playgroud)

配置:

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    ...
    <property name="interceptors">
        <list>
            <bean class="com.blah.AddHttpHeaderInterceptor" />
        </list>
    </property>
</bean>
Run Code Online (Sandbox Code Playgroud)

  • 对于将来的用户来说,好的答案是使用HttpComponentsConnection而不是CommonsHttpConnection,因为它已被弃用. (5认同)
  • 运行 JUnit 测试时它有效吗?就我而言,它没有,因为 `context.getConnection()` 返回 `MockSenderConnection`。我正在使用“MockWebServiceServer”进行单元测试。 (2认同)

Tom*_*icz 24

ClientInterceptor适用于静态标头值.但是,当每个请求应该应用不同的值时,不可能使用它.在这种情况下WebServiceMessageCallback是有帮助的:

final String dynamicParameter = //...

webServiceOperations.marshalSendAndReceive(request, 
    new WebServiceMessageCallback() {
        void doWithMessage(WebServiceMessage message) {
            TransportContext context = TransportContextHolder.getTransportContext();
            CommonsHttpConnection connection = (CommonsHttpConnection) context.getConnection();
            PostMethod postMethod = connection.getPostMethod();
            postMethod.addRequestHeader( "fsreqid", dynamicParameter );
        }
}
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,'org.springframework.ws.transport.http.CommonsHttpConnection`已被弃用,以支持`org.springframework.ws.transport.http.HttpComponentsConnection`. (4认同)
  • 我认为这个解决方案在运行 JUnit 测试时不起作用,因为 `context.getConnection()` 返回 `MockSenderConnection`。我正在使用“MockWebServiceServer”进行单元测试。 (2认同)

ruh*_*kus 11

使用spring integration 3和spring integration-ws时,可以使用以下代码处理请求:

public boolean handleRequest(MessageContext messageContext)
        throws WebServiceClientException {
    TransportContext context = TransportContextHolder.getTransportContext();
    HttpUrlConnection connection = (HttpUrlConnection) context
    .getConnection();
    connection.getConnection().addRequestProperty("HEADERNAME",
    "HEADERVALUE");

    return true;
}
Run Code Online (Sandbox Code Playgroud)

Interceptor可以通过以下方式连接到出站网关:

<ws:outbound-gateway ...            
        interceptor="addPasswordHeaderInterceptor" >
</ws:outbound-gateway>

<bean id="addPasswordHeaderInterceptor class="com.yourfirm.YourHttpInterceptor" />
Run Code Online (Sandbox Code Playgroud)


And*_*lko 6

实际上,它是@Tomasz答案的更新版本,但提供了新的 Spring-WS API、Java 8 快捷方式,并关心WebServiceMessageCallback使用单独的方法创建实例。

我相信这是更加明显和自足的。

final class Service extends WebServiceGatewaySupport {

    /**
     * @param URL       the URI to send the message to
     * @param payload   the object to marshal into the request message payload
     * @param headers   HTTP headers to add to the request
     */
    public Object performRequestWithHeaders(String URL, Object payload, Map<String, String> headers) {
        return getWebServiceTemplate()
                .marshalSendAndReceive(URL, payload, getRequestCallback(headers));
    }

    /**
     * Returns a {@code WebServiceMessageCallback} instance with custom HTTP headers.
     */
    private WebServiceMessageCallback getRequestCallback(Map<String, String> headers) {
        return message -> {
            TransportContext context = TransportContextHolder.getTransportContext();
            HttpUrlConnection connection = (HttpUrlConnection)context.getConnection();
            addHeadersToConnection(connection, headers);
        };
    }

    /**
     * Adds all headers from the {@code headers} to the {@code connection}.
     */
    private void addHeadersToConnection(HttpUrlConnection connection, Map<String, String> headers){
        headers.forEach((name, value) -> {
            try {
                connection.addRequestHeader(name, value);
            } catch (IOException e) {
                e.printStackTrace(); // or whatever you want
            }
        });
    }

}
Run Code Online (Sandbox Code Playgroud)