2010-07-02 12 views
26

के साथ गतिशील रूप से कस्टम HTTP शीर्षलेख सेट करना आप स्प्रिंग-डब्ल्यूएस का उपयोग करते समय क्लाइंट पक्ष पर गतिशील रूप से कस्टम HTTP शीर्षलेख (SOAP शीर्षलेख नहीं) कैसे सेट करते हैं?स्प्रिंग-डब्ल्यूएस क्लाइंट

उत्तर

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

} 

config:

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

भविष्य में उपयोगकर्ताओं के लिए अच्छा जवाब, CommonsHttpConnection के बजाय HttpComponentsConnection का उपयोग करें, क्योंकि इसे बहिष्कृत कर दिया गया है। – dardo

+0

क्या यह जुनीट परीक्षण चलाते समय काम करता है? मेरे मामले में ऐसा इसलिए नहीं हुआ क्योंकि 'context.getConnection()' 'MockSenderConnection' लौटाता है। मैं यूनिट परीक्षण के लिए 'मॉकवेब सेवा सर्वर' का उपयोग कर रहा हूं। – Gooseman

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

यह समाधान क्लाइंट इंटरसेप्टर का उपयोग करने से अधिक लचीला है। आईएमएचओ, यह पसंदीदा होना चाहिए। इस लाइन context.getConnection() org.springframework.ws.transport.http.HttpServletConnection org.springframework.ws.transport.http में ढाला नहीं जा सकता पर : –

+0

मैं निम्नलिखित अपवाद हो रही है java.lang.ClassCastException .CommonsHttpConnection –

+3

FYI, 'org.springframework.ws.transport.http.CommonsHttpConnection' को' org.springframework.ws.transport.http.HttpComponentsConnection' के पक्ष में बहिष्कृत कर दिया गया है। – ZeroOne

0

निम्नलिखित टुकड़ा स्प्रिंग 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<MyWsResponse> response = (JAXBElement<MyWsResponse>) 
     wsTemplate.marshalSendAndReceive(MyWsOP, wsCallback); 
+0

सवाल "था कैसे आप एक कस्टम सेट करूँ HTTP हेडर (SOAP शीर्षलेख नहीं) ", लेकिन यह उत्तर वास्तव में एक SOAP शीर्षलेख जोड़ता है, न कि HTTP शीर्षलेख। – ZeroOne

1

वसंत के webServiceTemplate.marshalSendAndReceive (अनुरोध) विधि आंतरिक रूप से जोड़ देती नेटवर्क पर सोप संदेश भेजने के लिए HttpComponentsMessageSender उपयोग करता है और यह आगे सर्वर के साथ http कनेक्शन बनाने के लिए WebServiceConnection उपयोग करता है। आपको बस अपना खुद का कस्टम HttpComponentsMessageSender लिखना है और कुकी को postMethod के अंदर सेट करना है।

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

स्प्रिंग विन्यास:

<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 अनुरोध करने से पहले प्रत्येक अनुरोध में इसकी कस्टम कुकी सेट होगी।

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 के उत्तर का एक अद्यतन संस्करण है, लेकिन एक नया स्प्रिंग-डब्ल्यूएस एपीआई, जावा 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

मैं इस कक्षा का उपयोग कैसे करूं? मेरे पास पहले से ही डब्लूएसडीएल से उत्पन्न एक सेवा वर्ग है। – Pretty

+0

@ प्रेट्टी, एक यूआरएल और वहां निर्दिष्ट एक पेलोड का उपयोग करें, और उन्हें यहां पास करें – Andrew