2010-10-28 16 views
11

¿Cómo puedo agregar encabezados SOAP al cliente Spring Jax-WS?Cómo agregar encabezados SOAP al cliente Spring Jax-WS?

Específicamente, tengo un objeto Jaxb que me gustaría agregar al encabezado, pero se apreciarán ejemplos de xml.

Estoy usando Spring's JaxWsPortProxyFactoryBean descrito here. Además, estoy generando mi cliente como se describe en here, que está trabajando menos los encabezados que necesito agregar.

Gracias.

Respuesta

6

Todavía estoy tratando de encontrar una forma elegante de agregar encabezados, pero lo que hago como otros sugieren es utilizar un transformador en WebServiceMessageCallBack(). Aquí hay un código de ejemplo:

JAXBElement<GetDeletedResponse> result = (JAXBElement<GetDeletedResponse>) webServiceTemplate.marshalSendAndReceive(request, new WebServiceMessageCallback() { 
public void doWithMessage(WebServiceMessage webServiceMessage) { 
    try { 
     SoapMessage soapMessage = (SoapMessage) webServiceMessage; 
     soapMessage.setSoapAction("getDeleted"); 

     SoapHeader header = soapMessage.getSoapHeader(); 
     StringSource headerSource = new StringSource("<account>\n" + 
           "<username>"+"johnsmith"+"</username>\n" + 
           "<password>"+"1234"+"</password>\n" + 
           "</account>"); 
     Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
     transformer.transform(headerSource, header.getResult()); 

     } catch (Exception e) { 
     new RuntimeException(e); 
     } 
} 
... 

No es realmente elegante, teniendo en cuenta que esto es Spring's WS. No es intuitivo.

14

Un poco más elegante (todavía se requiere un elenco de clase):

public void doWithMessage(WebServiceMessage message) { 
    try { 
     SOAPMessage soapMessage = ((SaajSoapMessage)message).getSaajMessage(); 
     SOAPHeader header = soapMessage.getSOAPHeader(); 
     SOAPHeaderElement security = header.addHeaderElement(new QName("http://schemas.xmlsoap.org/ws/2003/06/secext", "Security", "wsse")); 
     SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse"); 
     SOAPElement username = usernameToken.addChildElement("Username", "wsse"); 
     SOAPElement password = usernameToken.addChildElement("Password", "wsse"); 

     username.setTextContent(someUsername); 
     password.setTextContent(somePassword); 
    } catch (Exception e) { 
     //... handle appropriately 
    } 
} 

Nota: Este ejemplo ha sido testículos con Spring WS 2.1.4.

5

Después de hurgar un poco si se encuentra una solución ligeramente diferente. Estoy usando JAXB para organizar mi carga y las posibles clases de encabezado también se han generado con JAXB desde WSDL. En mi caso, me dirijo a Microsoft Reporting Services y he transferido un ExecutionID como encabezado SOAP.

public class ReportExecution2005Client extends WebServiceGatewaySupport { 

    private static final String SET_EXECUTION_PARAMETERS_ACTION = "http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices/SetExecutionParameters"; 

    private final class SoapActionExecutionIdCallback implements WebServiceMessageCallback { 

     private final String soapAction; 
     private final String executionId; 

     public SoapActionExecutionIdCallback(String soapAction, String executionId) { 
      super(); 
      this.soapAction = soapAction; 
      this.executionId = executionId; 
     } 

     @Override 
     public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException { 
      SoapMessage soapMessage = (SoapMessage) message; 
      soapMessage.setSoapAction(soapAction); 
      ExecutionHeader executionHeader = new ExecutionHeader(); 
      executionHeader.setExecutionID(executionId); 
      getMarshaller().marshal(executionHeader, soapMessage.getSoapHeader().getResult()); 
     } 
    } 

    public void setExecutionParameters(String executionId){ 
     SetExecutionParameters request = new SetExecutionParameters(); 
     request.setParameters(new ArrayOfParameterValue()); 

     SetExecutionParametersResponse response = (SetExecutionParametersResponse) getWebServiceTemplate().marshalSendAndReceive(request, 
       new SoapActionExecutionIdCallback(
         SET_EXECUTION_PARAMETERS_ACTION, 
         executionId)); 
    } 
} 

Básicamente, el WebServiceGatewaySupport ya conoce la Marshaller para convertir JAXB Pojos. Estoy usando ésta para fijar mis propias clases de cabecera a la SoapHeader con esta línea:

getMarshaller().marshal(executionHeader, soapMessage.getSoapHeader().getResult()); 

en mi WebServiceMessageCallback anidada.

Cuestiones relacionadas