2010-07-02 26 views

Trả lời

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

Câu trả lời hay cho người dùng trong tương lai, hãy sử dụng HttpComponentsConnection thay vì CommonsHttpConnection, vì nó không được chấp nhận. – dardo

+0

Tính năng này có hoạt động khi chạy thử nghiệm JUnit không? Trong trường hợp của tôi, nó không phải vì 'context.getConnection()' trả về 'MockSenderConnection'. Tôi đang sử dụng 'MockWebServiceServer' để kiểm tra Đơn vị. – Gooseman

20

ClientInterceptor hoạt động tuyệt vời cho giá trị tiêu đề tĩnh. Nhưng nó không thể sử dụng nó khi một giá trị khác nhau nên được áp dụng cho mỗi yêu cầu. Trong trường hợp đó WebServiceMessageCallback hữu ích:

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

Giải pháp này linh hoạt hơn việc sử dụng trình chặn khách hàng. IMHO, nó nên được ưa thích nhất. –

+0

tôi nhận được ngoại lệ sau đây java.lang.ClassCastException: trên dòng này context.getConnection() org.springframework.ws.transport.http.HttpServletConnection không thể được đúc để org.springframework.ws.transport.http .CommonsHttpConnection –

+3

FYI, 'org.springframework.ws.transport.http.CommonsHttpConnection' đã không được hỗ trợ cho' org.springframework.ws.transport.http.HttpComponentsConnection'. – ZeroOne

0

Đoạn sau đã được thử nghiệm với Spring 4.0. Nó gắn thêm một WebServiceMessageCallback đến một phương pháp 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

Câu hỏi đặt ra là "Làm thế nào để bạn thiết lập một HTTP tùy chỉnh header (không phải là tiêu đề SOAP) ", nhưng câu trả lời này thực sự thêm một tiêu đề SOAP, không phải là một tiêu đề HTTP. – ZeroOne

1

Spring webServiceTemplate.marshalSendAndReceive (theo yêu cầu) trong nội bộ sử dụng HttpComponentsMessageSender để gửi tin nhắn SOAP trên mạng và điều này tiếp tục sử dụng WebServiceConnection để làm cho kết nối với máy chủ http. Tất cả bạn phải làm là viết HttpComponentsMessageSender tùy chỉnh của riêng bạn và đặt cookie bên trong postMethod. đang gửi

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

Xuân Cấu hình:

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

Sau này, tôi chỉ đơn giản là có được đậu webServiceTemplate và gọi phương thức marshalSendAndReceive. Vì vậy, mọi yêu cầu sẽ có tập hợp cookie tùy chỉnh của nó trước khi thực hiện cuộc gọi HTTP.

9

Khi sử dụng tích hợp mùa xuân 3 và mùa xuân hội nhập-ws, mã sau đây có thể được sử dụng để xử lý các yêu cầu:

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

    return true; 
} 

Các Interceptor có thể được kết nối với cổng đi theo cách sau:

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

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

Trên thực tế, đây là phiên bản cập nhật của câu trả lời của @Tomasz, nhưng cung cấp API Spring-WS mới, phím tắt Java 8 và quan tâm đến việc tạo cá thể WebServiceMessageCallback với phương pháp riêng.

Tôi tin rằng điều đó rõ ràng hơn và tự cung tự cấp.

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

Tôi sẽ sử dụng lớp học này như thế nào? Tôi đã có một lớp dịch vụ được tạo từ WSDL rồi. – Pretty

+0

@Pretty, sử dụng URL và tải trọng được chỉ định ở đó và chuyển chúng tại đây – Andrew

Các vấn đề liên quan