Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAX-WS - Adding SOAP Headers

I am trying to create a standalone client to consume some web services. I must add my username and password to the SOAP Header. I tried adding the credentials as follows:

OTSWebSvcsService service = new OTSWebSvcsService(); OTSWebSvcs port = service.getOTSWebSvcs();  BindingProvider prov = (BindingProvider)port; prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myusername"); prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypassword");  ... 

When I call a method on the service I get the following exception:

com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5048E: One of "SOAP Header" elements required. 

What am I doing wrong? How would I add these properties to the SOAP Header?

Edited: I was using JAX-WS 2.1 included in JDK6. I am now using JAX-WS 2.2. I now get the following exception:

com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5509E: A security token whose type is [http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken] is required. 

How do I go about creating this token?

like image 925
Jordan Allan Avatar asked Feb 24 '10 00:02

Jordan Allan


People also ask

How do you set the SOAP header in JAX-WS client?

Creating a JAX-WS handler for SOAP header information To create a JAX-WS handler to access SOAP header information, first create a basic Java API for XML Web Services (JAX-WS) handlers for your export or import. It will create stubs for the methods. You next need to implement the handleMessage method.

How do I add a SOAP header in WSDL?

You can add soap header information to method calls by decorating the methods in the proxy class generated from the wsdl with the SoapHeader attribute. For example wsdl.exe will generate client proxy class Reference. cs for the web service reference when you "Add Web Reference".


2 Answers

Data can be transferred in SOAP header (JaxWS) by using @WebParam(header = true):

@WebMethod(operationName = "SendRequest", action = "http://abcd.ru/") @Oneway public void sendRequest(     @WebParam(name = "Message", targetNamespace = "http://abcd.ru/", partName = "Message")     Data message,     @WebParam(name = "ServiceHeader", targetNamespace = "http://abcd.ru/", header = true, partName = "ServiceHeader")     Header serviceHeader); 

If you want to generate a client with SOAP Headers, you need to use -XadditionalHeaders:

wsimport -keep -Xnocompile -XadditionalHeaders -Xdebug http://12.34.56.78:8080/TestHeaders/somewsdl?wsdl -d /home/evgeny/DEVELOPMENT/JAVA/gen 

If don't need @Oneway web service, you can use Holder:

@WebMethod(operationName = "SendRequest", action = "http://abcd.ru/") public void sendRequest(     @WebParam(name = "Message", targetNamespace = "http://abcd.ru/", partName = "Message")     Data message,     @WebParam(name = "ServiceHeader", targetNamespace = "http://abcd.ru/", header = true, partName = "ServiceHeader")     Holder<Header> serviceHeader); 
like image 62
Evgeny Avatar answered Sep 25 '22 20:09

Evgeny


Not 100% sure as the question is missing some details but if you are using JAX-WS RI, then have a look at Adding SOAP headers when sending requests:

The portable way of doing this is that you create a SOAPHandler and mess with SAAJ, but the RI provides a better way of doing this.

When you create a proxy or dispatch object, they implement BindingProvider interface. When you use the JAX-WS RI, you can downcast to WSBindingProvider which defines a few more methods provided only by the JAX-WS RI.

This interface lets you set an arbitrary number of Header object, each representing a SOAP header. You can implement it on your own if you want, but most likely you'd use one of the factory methods defined on Headers class to create one.

import com.sun.xml.ws.developer.WSBindingProvider;  HelloPort port = helloService.getHelloPort();  // or something like that... WSBindingProvider bp = (WSBindingProvider)port;  bp.setOutboundHeader(   // simple string value as a header, like <simpleHeader>stringValue</simpleHeader>   Headers.create(new QName("simpleHeader"),"stringValue"),   // create a header from JAXB object   Headers.create(jaxbContext,myJaxbObject) ); 

Update your code accordingly and try again. And if you're not using JAX-WS RI, please update your question and provide more context information.

Update: It appears that the web service you want to call is secured with WS-Security/UsernameTokens. This is a bit different from your initial question. Anyway, to configure your client to send usernames and passwords, I suggest to check the great post Implementing the WS-Security UsernameToken Profile for Metro-based web services (jump to step 4). Using NetBeans for this step might ease things a lot.

like image 45
Pascal Thivent Avatar answered Sep 24 '22 20:09

Pascal Thivent