简体   繁体   中英

Add a header on Web Service request using CXF

How do you add a header on Web Service client request that looks like below XML?
The xml below is a request auto-generated by SOAP UI and its working fine given the correct username/password.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dof="http://dof.ad.com">
   <soapenv:Header>
      <dof:UserCredentials>
         <!--Optional:-->
         <dof:userName></dof:userName>
         <!--Optional:-->
         <dof:password></dof:password>
      </dof:UserCredentials>
   </soapenv:Header>
   <soapenv:Body>
      <dof:CheckService/>
   </soapenv:Body>
</soapenv:Envelope>

I'd like to know how the header portion can be added using apache CXF. I've auto-generated a code using CXF from WSDL (see below) and checked various articles but the code is still not working. I am assuming the request being sent is not correct or it doesn't have a header.

public static void checkServiceMan() {
    String address = "https://WSDL_URL";

    JaxWsProxyFactoryBean jaxWsProxy = new JaxWsProxyFactoryBean();
    jaxWsProxy.setServiceClass(DOFairservice.class);
    jaxWsProxy.setAddress(address);

    DOFairservice serviceClient = (DOFairservice) jaxWsProxy.create();

    ObjectFactory factory = new ObjectFactory();
    UserCredentials uc = factory.createUserCredentials();
    uc.setUserName("username");
    uc.setPassword("password");

    List<Header> headerList = new ArrayList<Header>();
    try {

        Header testCredentialsHeader = new Header(new QName("http://DOF", "DOFairservice")
                ,uc
                ,new JAXBDataBinding(UserCredentials.class));

        headerList.add(testCredentialsHeader);

    } catch (JAXBException e) {

        e.printStackTrace();
    }
    ((BindingProvider) serviceClient).getResponseContext().put(Header.HEADER_LIST, headerList);

    Client client = ClientProxy.getClient(serviceClient);
    HTTPConduit conduit = (HTTPConduit) client.getConduit();
    HTTPClientPolicy policy = conduit.getClient();
    policy.setReceiveTimeout(10000);

    String resp = serviceClient.checkService(); **<--- ERROR HERE**
    System.out.println("Response from Customs Web Service: "+ resp);

    System.out.println("Web Service Header Test Done");
}

Error Message

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Error reading XMLStreamReader: Unexpected character '8' (code 56) in prolog; expected '<'
 at [row,col {unknown-source}]: [1,1]
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
    at com.sun.proxy.$Proxy45.checkService(Unknown Source)
    at ae.abudhabi.dof.client.CheckServiceClient.checkServiceMan(CheckServiceClient.java:103)
    at ae.abudhabi.dof.client.CheckServiceClient.main(CheckServiceClient.java:112)
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '8' (code 56) in prolog; expected '<'

I found a simple solution to add headers on the requests I sent to the Web Service. All I needed to do was just to add the extra code below on my Maven CXF plugin build.

<extendedSoapHeaders>true</extendedSoapHeaders>

The extra line above only works if the soap header portion is explicitly declared in the wsdl which is in my case.

<wsdl:input>
<soap:body use="literal"/>
<soap:header message="tns:CheckUserCredentials" part="UserCredentials" use="literal"/>
</wsdl:input>

I re-generated the source and modified see below

public static void checkServiceMan() {
    String address = "https://WSDL_URL";

    JaxWsProxyFactoryBean jaxWsProxy = new JaxWsProxyFactoryBean();
    jaxWsProxy.setServiceClass(DOFairservice.class);
    jaxWsProxy.setAddress(address);

    DOFairservice serviceClient = (DOFairservice) jaxWsProxy.create();

    ObjectFactory factory = new ObjectFactory();
    UserCredentials uc = factory.createUserCredentials();
    uc.setUserName("username");
    uc.setPassword("password");

    String resp = serviceClient.checkService(uc); **<--- New Argument Here**
    System.out.println("Response from Customs Web Service: "+ resp);

    System.out.println("Web Service Header Test Done");
}

Everything was working fine and the header is now inserted to the XML requests sent to the web service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM