2010-07-02 128 views

回答

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

} 

配置:

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> 
    ... 
    <property name="interceptors"> 
     <list> 
      <bean class="com.blah.AddHttpHeaderInterceptor" /> 
     </list> 
    </property> 
</bean> 
+4

对于将来的用户来说,好的答案是使用HttpComponentsConnection而不是CommonsHttpConnection,因为它已被弃用。 – dardo 2012-07-02 20:13:38

+0

运行JUnit测试时工作吗?在我的情况下,它并不是因为'context.getConnection()'返回'MockSenderConnection'。我正在使用'MockWebServiceServer'进行单元测试。 – Gooseman 2015-12-31 00:21:00

20

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

该解决方案比使用客户端拦截器更灵活。恕我直言,它应该是首选。 – 2013-09-14 10:27:00

+0

我得到以下异常 java.lang.ClassCastException: 在这条线context.getConnection() org.springframework.ws.transport.http.HttpServletConnection不能转换为org.springframework.ws.transport.http .CommonsHttpConnection – 2014-05-03 07:19:38

+3

仅供参考,'org.springframework.ws.transport.http.CommonsHttpConnection'已被弃用,以支持'org.springframework.ws.transport.http.HttpComponentsConnection'。 – ZeroOne 2015-05-20 14:18:03

0

以下片段已用Spring 4.0进行过测试。它附加一个WebServiceMessageCallbackorg.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<MyWsResponse> response = (JAXBElement<MyWsResponse>) 
     wsTemplate.marshalSendAndReceive(MyWsOP, wsCallback); 
+0

的问题是“你如何设置自定义HTTP头(不是SOAP头)“,但是这个答案实际上增加了一个SOAP头,而不是一个HTTP头。 – ZeroOne 2015-05-20 13:44:13

1

Spring的webServiceTemplate.marshalSendAndReceive(request)方法内部使用HttpComponentsMessageSender到通过网络发送SOAP消息,这还使用WebServiceConnection使与服务器的HTTP连接。你所要做的就是编写你自己定制的HttpComponentsMessageSender并在postMethod中设置cookie。

Custome发送代码:

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 = "<Your Custom Cookie>"; 

postMethod.addHeader("Cookie", cookie); 

return conn; 
} 
} 

Spring配置文件:

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMe ssageFactory" /> 

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshalle r"> 
<property name="contextPath" value="com.swap.provision" /> 
</bean> 

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServi ceTemplate"> 
<constructor-arg ref="messageFactory" /> 
<property name="marshaller" ref="marshaller"></property> 
<property name="unmarshaller" ref="marshaller"></property> 
<property name="messageSender" ref="urlMessageSender"/> 
<property name="defaultUri" value=<Server URL> /> 
</bean> 

此我简单地得到豆webServiceTemplate并调用marshalSendAndReceive方法后。因此,在进行HTTP调用之前,每个请求都会设置自定义cookie。

9

当使用弹簧一体化3和弹簧一体化-WS,以下代码可被用于处理该请求:

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

    return true; 
} 

拦截器可以连接到所述出站网关以下列方式:

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

<bean id="addPasswordHeaderInterceptor class="com.yourfirm.YourHttpInterceptor" /> 
1

实际上,它是@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 
      } 
     }); 
    } 

} 
+0

我将如何使用这个类?我有一个从WSDL生成的服务类。 – Pretty 2017-12-04 05:27:08

+0

@Pretty,使用指定的URL和有效载荷,并在这里传递它们 – Andrew 2017-12-04 17:38:24

相关问题