2012-09-12 36 views
5

Chúng tôi cần tiêu thụ các dịch vụ web được phát triển bởi nhóm khác. Sử dụng JAX-WS để tạo các dịch vụ web. Chúng tôi đang sử dụng wsimport để tạo ra các mặt hàng phía khách hàng.Cách thêm tiêu đề SOAP vào yêu cầu SOAP bằng JAX-WS?

Vấn đề là tôi cần phải vượt qua các thông tin sau đây là một tiêu đề cùng với cơ thể SOAP:

<soapenv:Header> 
    <ns1:HeaderData xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
        xmlns:ns1="http://www.example.com/esb/data_type/HeaderData/v1"> 
     <ChannelIdentifier>ABC</ChannelIdentifier> 
    </ns1:HeaderData> 
</soapenv:Header> 


Chúng tôi đang sử dụng:

BindingProvider.getRequestContext().put(
    BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
    serviceConfig.getServiceEndPoint() 
); 

để thiết lập các thiết bị đầu cuối.

Có ai có thể đề xuất cách chuyển tiêu đề theo yêu cầu không?

Cảm ơn, VK

Trả lời

12

sử dụng param header = true của @WebParam chú thích

@WebMethod 
@WebResult String method(
     @WebParam String anotherParam 
     @WebParam(header = true, mode = Mode.OUT) Holder<String> headerParam) 

header = true, mode = Mode.OUT nghĩa là param headerParam sẽ chỉ ra trong phần đầu.
Nếu bạn muốn điều này param này ở đầu vào và sản lượng, làm cho Mode.INOUT

+0

Câu trả lời này phải được chấp nhận. Ngắn gọn và chính xác. –

6

tôi đã có thêm thông tin người dùng vào tiêu đề vì vậy tôi đã làm cho nó như thế này:

private void modifyRequest(String username, String password) { 
    UserCredentials authHeader = new UserCredentials(); 
    authHeader.setUsername(username); 
    authHeader.setPassword(password); 
    ArrayList<Header> headers = new ArrayList<Header>(1); 
    try { 
     Header soapHeader = new Header(new QName(TQIntegrationV2.TQIntegrationV2Soap.getNamespaceURI(), "UserCredentials"), authHeader, new JAXBDataBinding(UserCredentials.class)); 
     headers.add(soapHeader); 
    } catch (JAXBException ex) { 
     LOGGER.error("Exception trying to serialize header: {}", ex); 
    } 
    ((BindingProvider) proxy).getRequestContext().put(Header.HEADER_LIST, headers); 
} 

Và tất cả mọi thứ hoạt động tốt. Mọi cuộc gọi tới dịch vụ web đều có tên người dùng và mật khẩu được chuyển đến tiêu đề này. Bạn có thể dễ dàng thay đổi điều này để làm việc trong trường hợp của bạn.

EDIT

Đoạn mã trên được sử dụng CXF API để sửa đổi tiêu đề. Tôi cũng đã thực hiện việc này bằng cách sử dụng JAX-WS. Nó gần như giống nhau, làm thay đổi tiêu đề để thêm thông tin người dùng:

public class MyHandler implements SOAPHandler<SOAPMessageContext> { 

    private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class); 

    private String username; 

    private String password; 

    /** 
    * Handles SOAP message. If SOAP header does not already exist, then method will created new SOAP header. The 
    * username and password is added to the header as the credentials to authenticate user. If no user credentials is 
    * specified every call to web service will fail. 
    * 
    * @param context SOAP message context to get SOAP message from 
    * @return true 
    */ 
    @Override 
    public boolean handleMessage(SOAPMessageContext context) { 
     try { 
      SOAPMessage message = context.getMessage(); 
      SOAPHeader header = message.getSOAPHeader(); 
      SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 
      if (header == null) { 
       header = envelope.addHeader(); 
      } 
      QName qNameUserCredentials = new QName("https://your.target.namespace/", "UserCredentials"); 
      SOAPHeaderElement userCredentials = header.addHeaderElement(qNameUserCredentials); 

      QName qNameUsername = new QName("https://your.target.namespace/", "Username"); 
      SOAPHeaderElement username = header.addHeaderElement(qNameUsername); 
      username.addTextNode(this.username); 
      QName qNamePassword = new QName("https://your.target.namespace/", "Password"); 
      SOAPHeaderElement password = header.addHeaderElement(qNamePassword); 
      password.addTextNode(this.password); 

      userCredentials.addChildElement(username); 
      userCredentials.addChildElement(password); 

      message.saveChanges(); 
      //TODO: remove this writer when the testing is finished 
      StringWriter writer = new StringWriter(); 
      message.writeTo(new StringOutputStream(writer)); 
      LOGGER.debug("SOAP message: \n" + writer.toString()); 
     } catch (SOAPException e) { 
      LOGGER.error("Error occurred while adding credentials to SOAP header.", e); 
     } catch (IOException e) { 
      LOGGER.error("Error occurred while writing message to output stream.", e); 
     } 
     return true; 
    } 

    //TODO: remove this class after testing is finished 
    private static class StringOutputStream extends OutputStream { 

     private StringWriter writer; 

     public StringOutputStream(StringWriter writer) { 
      this.writer = writer; 
     } 

     @Override 
     public void write(int b) throws IOException { 
      writer.write(b); 
     } 
    } 

    @Override 
    public boolean handleFault(SOAPMessageContext context) { 
     LOGGER.debug("handleFault has been invoked."); 
     return true; 
    } 

    @Override 
    public void close(MessageContext context) { 
     LOGGER.debug("close has been invoked."); 
    } 

    @Override 
    public Set<QName> getHeaders() { 
     LOGGER.debug("getHeaders has been invoked."); 
     return null; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 

Và tôi xác định xử lý này trong Spring cấu hình như thế này:

<bean id="soapHandler" class="your.package.MyHandler"> 
    <property name="username" value="testUser"/> 
    <property name="password" value="testPassword"/> 
</bean> 

<jaxws:client "..."> 
    <jaxws:handlers> 
     <ref bean="soapHandler"/> 
    </jaxws:handlers> 
</jaxws:client> 

Tất cả bạn cần làm là thực hiện giao diện SOAPHandler<SOAPMessageContext> , ghi đè lên các phương thức của nó và sau đó bạn có thể làm những gì bạn muốn với thông báo SOAP.

+0

Cảm ơn bạn đã trả lời. Bạn có thể đăng tên đầy đủ của lớp Tiêu đề. Chỉ muốn tìm xem nó là từ jaxws api. – ikvenu2000

+0

Tiêu đề không phải từ JAX-WS từ CXF, tôi đã chỉnh sửa câu trả lời cách sửa đổi tiêu đề trong JAX-WS. –

+0

Mã JAX-WS đó hoạt động hoàn hảo, cảm ơn! – kai

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