使用Spring-WS客户端动态设置自定义HTTP标头
在使用Spring-WS时,如何在客户端动态设置自定义HTTP头(而不是SOAP头)?
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(); CommonsHttpConnection connection = (CommonsHttpConnection) context.getConnection(); PostMethod postMethod = connection.getPostMethod(); postMethod.addRequestHeader( "fsreqid", "123456" ); return true; } public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException { return true; } }
配置:
...
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 ); } }
使用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; }
Interceptor可以通过以下方式连接到出站网关:
Spring的webServiceTemplate.marshalSendAndReceive(request)方法在内部使用HttpComponentsMessageSender通过网络发送SOAP消息,这进一步使用WebServiceConnection与服务器建立http连接。 您所要做的就是编写自己的自定义HttpComponentsMessageSender并在postMethod中设置cookie。
客户发件人代码:
package com.swap.ws.sender; import java.io.IOException; import java.net.URI; import javax.annotation.Resource; import org.apache.http.client.methods.HttpPost; import org.apache.log4j.Logger; import org.springframework.stereotype.Service; import org.springframework.ws.transport.WebServiceConnect ion; import org.springframework.ws.transport.http.HttpComponen tsConnection; /** * * @author swapnil Z */ @Service("urlMessageSender") public class CustomHttpComponentsMessageSender extends org.springframework.ws.transport.http.HttpComponen tsMessageSender { private static Logger _logger = Logger.getLogger(""); @Override public WebServiceConnection createConnection(URI uri) throws IOException { String cookie = null; HttpComponentsConnection conn = (HttpComponentsConnection) super .createConnection(uri); HttpPost postMethod = conn.getHttpPost(); cookie = ""; postMethod.addHeader("Cookie", cookie); return conn; } }
弹簧配置:
/>
在此之后,我只需获取bean webServiceTemplate并调用marshalSendAndReceive方法。 因此,每个请求都会在进行HTTP调用之前设置自定义cookie。
实际上,它是@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 headers) { return getWebServiceTemplate() .marshalSendAndReceive(URL, payload, getRequestCallback(headers)); } /** * Returns a {@code WebServiceMessageCallback} instance with custom HTTP headers. */ private WebServiceMessageCallback getRequestCallback(Map 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 headers){ headers.forEach((name, value) -> { try { connection.addRequestHeader(name, value); } catch (IOException e) { e.printStackTrace(); // or whatever you want } }); } }
使用java 1.8的示例方法:如何添加HTTP标头:
public void executeObjectWebservice(String id) { ExecuteObject request = new ExecuteObject(); getWebServiceTemplate().marshalSendAndReceive("http://url/webservice-test/uc4ws", new ObjectFactory().createExecuteObject(request), new WebServiceMessageCallback() { public void doWithMessage(WebServiceMessage message) throws IOException { TransportContext context = TransportContextHolder.getTransportContext(); HttpUrlConnection connection = (HttpUrlConnection) context.getConnection(); connection.addRequestHeader("ID", id); } }); }
说明 :使用getWebServiceTemplate()。marshalSendAndReceive,如下所示: https ://spring.io/guides/gs/consuming-web-service/
第一个参数是URI,第二个是与请求一起发送的对象。 作为第三个参数,您可以添加为function
new WebServiceMessageCallback()
你重写public void doWithMessage
。 在发送请求之前调用此方法。 您可以在其中访问该消息并添加请求标题
TransportContext context = TransportContextHolder.getTransportContext(); HttpUrlConnection connection = (HttpUrlConnection) context.getConnection(); connection.addRequestHeader("ID", id);
以下片段已在Spring 4.0中测试过。 它将一个WebServiceMessageCallback
附加到org.springframework.ws.client.core.WebServiceTemplate
final String DYNAMICVALUE = "myDynamo"; WebServiceMessageCallback wsCallback = new WebServiceMessageCallback() { public void doWithMessage(WebServiceMessage message) { try { SoapMessage soapMessage = (SoapMessage)message; SoapHeader header = soapMessage.getSoapHeader(); header.addAttribute(new QName("myHeaderElement"), DYNAMICVALUE); } catch (Exception e) { e.printStackTrace(); } } }; JAXBElement response = (JAXBElement ) wsTemplate.marshalSendAndReceive(MyWsOP, wsCallback);