How to add a soap header when creating a soap request using java objects created by wsdl

I created client Java objects using JAX-WS RI. I am trying to make a SOAP request to a web service. The service requires authentication in the header, which looks like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <xsd:authHeader> <xsd:user> username@gmail.com </xsd:user> <xsd:password>password1</xsd:password> </xsd:authHeader> </soapenv:Header> <soapenv:Body> <ns:searchAssetsParam> <ns:includeSubfolders>true</ns:includeSubfolders> <ns:resultsPage>2</ns:resultsPage> </ns:searchAssetsParam> </soapenv:Body> </soapenv:Envelope> 

Generated Java objects have methods for calling a service, creating objects, and constructing a header. But when making a call, I am having problems setting the header.

Here is the code I'm using:

 IpsApiService service = new IpsApiService(); IpsApiPortType port = service.getIpsApiSoapPort(); SearchAssetsParam searchAssetsParam = buildSearchAssetsParam(); SearchAssetsReturn response = port.searchAssets(searchAssetsParam); 

buildSearchAssetsParam () creates a query object. I created the header object as follows:

 AuthHeader header = new AuthHeader(); header.setUser(" username@gmail.com "); header.setPassword("password1"); 

How to configure this AuthHeader to request a service?

Thanks Venu

+4
source share
4 answers

I once had the same problem. I needed to change the header of the JAX-WS SOAP web service for each request. To solve this problem, I created a handler as follows:

 public class MyHandler implements SOAPHandler<SOAPMessageContext> { private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class); private String username; private String password; @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; } } 

It adds the necessary parameters to my SOAP header, and it is called on every request. All you have to do is change the handleMessage method to suit your needs.

+7
source

It works for me, overriding the public void setAttribute(String namespace, String localName, String value) method.

 import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.message.SOAPHeaderElement; @SuppressWarnings("serial") public class ADESHeaderElement extends SOAPHeaderElement { public ADESHeaderElement(QName qname, Object value) { super(qname, value); } @Override public void setAttribute(String namespace, String localName, String value) { if (!Constants.ATTR_MUST_UNDERSTAND.equals(localName)) { // Or any other attribute name you'd want to avoid super.setAttribute(namespace, localName, value); } } } 

Create a title element as follows:

  ADESHeaderElement custheader = new ADESHeaderElement(qname, clientserv); custheader.setActor(null); 
+1
source

When you create your service from a class generated by cxf, add a custom interceptor

 Service service = new MyService(wsdlURL, new QName("http://myservice.com/MyService/", "MyService")); MyPort port = service.getMyPort(); Client client = ClientProxy.getClient(port); // adding interceptor programmatically client.getOutInterceptors().add(new MyHeaderHandler()); 

You can extend AbstractSoapInterceptor to implement your custom interceptor to handle the message.

 import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.headers.Header; import org.apache.cxf.jaxb.JAXBDataBinding; import org.apache.cxf.phase.Phase; import com.rpc.core.utils.DomainContext; public class MyHeaderHandler extends AbstractSoapInterceptor { /** * Constructor */ public MyHeaderHandler() { super(Phase.PRE_LOGICAL); } @Override public void handleMessage(org.apache.cxf.binding.soap.SoapMessage message) throws org.apache.cxf.interceptor.Fault { try { message.getHeaders().add(new Header(new QName("MyCustomHeader"),"value", new JAXBDataBinding(String.class))); } catch (JAXBException e) { e.printStackTrace(); } }; } } 
+1
source

Yes, I did the same as Rangappa Tungal, following this example:

 Service w = new ServiceLocator(); ServiceSoap ws = new ServiceSoapStub(new URL(w.getServiceSoapAddress()),w); Stub mystub = (Stub) ws; AuthHeader up = new AuthHeader("user","pass"); mystub.setHeader("namespace", "AuthHeader", up); ws.get***(); 

Link to an example!

0
source

Source: https://habr.com/ru/post/952812/


All Articles