将SoapHeader添加到org.springframework.ws.WebServiceMessage

Mar*_*ope 13 java spring soap web-services spring-ws

如何将对象添加到a的soap标头中 org.springframework.ws.WebServiceMessage

这是我希望最终得到的结构:

 <soap:Header>
    <credentials xmlns="http://example.com/auth">
      <username>username</username>
      <password>password</password>
    </credentials>
  </soap:Header>
Run Code Online (Sandbox Code Playgroud)

Pas*_*ent 31

基本上,您需要WebServiceMessageCallback在客户端中使用a来在创建消息之后但在发送之前修改消息.@skaffman已经非常准确地描述了代码的其余部分,所以整个东西看起来像这样:

public void marshalWithSoapActionHeader(MyObject o) {

    webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {

        public void doWithMessage(WebServiceMessage message) {
            try {
                SoapMessage soapMessage = (SoapMessage)message;
                SoapHeader header = soapMessage.getSoapHeader();
                StringSource headerSource = new StringSource("<credentials xmlns=\"http://example.com/auth\">\n +
                        <username>"+username+"</username>\n +
                        <password>"+password"+</password>\n +
                        </credentials>");
                Transformer transformer = TransformerFactory.newInstance().newTransformer();
                transformer.transform(headerSource, header.getResult());
            } catch (Exception e) {
                // exception handling
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

就个人而言,我发现Spring-WS很难满足这样的基本需求,他们应该修复 SWS-479.

  • 谢谢帕斯卡,效果很好。我最终使用 javax.xml.bind.util.JAXBSource 而不是 StringSource,如下所示: JAXBSource headerSource = new JAXBSource(jaxbContext, credentials); (2认同)

小智 8

你可以这样做:

public class SoapRequestHeaderModifier implements WebServiceMessageCallback {
 private final String userName = "user";
 private final String passWd = "passwd";

 @Override
 public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
  if (message instanceof SaajSoapMessage) {
   SaajSoapMessage soapMessage = (SaajSoapMessage) message;
   MimeHeaders mimeHeader = soapMessage.getSaajMessage().getMimeHeaders();
   mimeHeader.setHeader("Authorization", getB64Auth(userName, passWd));
  }
 }

 private String getB64Auth(String login, String pass) {
  String source = login + ":" + pass;
  String retunVal = "Basic " + Base64.getUrlEncoder().encodeToString(source.getBytes());
  return retunVal;
 }
}
Run Code Online (Sandbox Code Playgroud)

然后

Object response = getWebServiceTemplate().marshalSendAndReceive(request, new SoapRequestHeaderModifier());
Run Code Online (Sandbox Code Playgroud)


ska*_*man 5

您需要将WebServiceMessageto转换为SoapMessage,它有一个getSoapHeader()可用于修改标头的方法。反过来,SoapHeader有各种添加元素的方法,包括getResult()(可以用作操作的输出Transformer.transform())。


小智 5

I tried many options and finally below one worked for me if you have to send soap header with authentication(Provided authentication object created by wsimport) and also need to set soapaction.

public Response callWebService(String url, Object request)

{
    Response res = null;
    log.info("The request object is " + request.toString());

    try {
        
        

        res = (Response) getWebServiceTemplate().marshalSendAndReceive(url, request,new WebServiceMessageCallback() {
                 @Override
                  public void doWithMessage(WebServiceMessage message) {
                    try {
                      // get the header from the SOAP message
                      SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();

                      // create the header element
                      ObjectFactory factory = new ObjectFactory();
                      Authentication auth =
                          factory.createAuthentication();
                      auth.setUser("****");
                      auth.setPassword("******");
                     ((SoapMessage) message).setSoapAction(
                                "soapAction");

                      JAXBElement<Authentication> headers =
                          factory.createAuthentication(auth);

                      // create a marshaller
                      JAXBContext context = JAXBContext.newInstance(Authentication.class);
                      Marshaller marshaller = context.createMarshaller();

                      // marshal the headers into the specified result
                      marshaller.marshal(headers, soapHeader.getResult());
                      
                    } catch (Exception e) {
                      log.error("error during marshalling of the SOAP headers", e);
                    }
                  }
                });

        
    } catch (Exception e) {
        e.printStackTrace();
    }
    return res;

}
  
Run Code Online (Sandbox Code Playgroud)