2010-07-02 124 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

相關問題