I am using Spring-WS for consuming Webservice which compains if SOAP envelop has empty header element. I figured out that default SOAPMessage implementation adds one.
How can I remove it?
Thanks in advance
http://docs.oracle.com/javaee/5/tutorial/doc/bnbhr.html:
The next line is an empty SOAP header. You could remove it by calling
header.detachNode after the getSOAPHeader call.
So here is the solution in plain SAAJ:
MessageFactory messageFactory = MessageFactory.newInstance("SOAP 1.2 Protocol");
SOAPMessage message = messageFactory.createMessage();
message.getSOAPHeader().detachNode(); // suppress empty header
And here is the solution using spring-ws WebServiceMessageCallback based on this thread:
public void marshalWithSoapActionHeader(MyObject o) {
webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage) message;
SOAPMessage soapMessage = saajSoapMessage.getSaajMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPHeader header = soapMessage.getSOAPHeader();
header.detachNode();
}
});
}
Related
I need to add header elements to a Soap Request, but the child elements inside the header dont have any prefix defined. When I try to add the element without specifing a prefix, this throws a exception.
private SOAPHeader addSecuritySOAPHeader(SOAPMessageContext context) {
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
envelope.addNamespaceDeclaration("S", "http://schemas.xmlsoap.org/soap/envelope/");
envelope.addNamespaceDeclaration("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
SOAPEnvelope header = envelope.getHeader();
// ACTION NODE
SOAPElement action = header.addChildElement("Action");
return header;
}
Last line produces next exception
"com.sun.xml.messaging.saaj.SOAPExceptionImpl: HeaderElements must be namespace qualified"
Heaser i need to create:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<Action xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif</Action>
</S:Header>
..............
</S:Envelope>
If I include any prefix, like S, request fail, server response with "Bad request"
How can i add a "clean" Action node?
Is I add a prefix in action:
SOAPElement action = header.addChildElement("Action","S");
Service responses with a "Bad request" message.
<S:Action xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif</S:Action>
Any help, please?
This should work:
#Test
public void someTest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
var header = soapEnvelope.getHeader();
var actionElement = header.addChildElement("Action", "prefix", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
actionElement.addTextNode("http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif");
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapMessage.writeTo(out);
System.out.println(new String(out.toByteArray()));
}
Prints:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><prefix:Action xmlns:prefix="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://cgbridge.rategain.com/2011A/ReservationService/HotelResNotif</prefix:Action></SOAP-ENV:Header><SOAP-ENV:Body/></SOAP-ENV:Envelope>
How do I make a java client to call a soap WebService method with parameters?
I've tried this class for a java client
import javax.xml.soap.*;
public class SOAPClientSAAJ {
public static void main(String args[]) throws Exception {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
String url = "http:localhost:8080/myproject/mywebservice?wsdl";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);
// print SOAP Response
System.out.print("Response SOAP Message:");
soapResponse.writeTo(System.out);
soapConnection.close();
}
private static SOAPMessage createSOAPRequest() throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String namespace= "http://wsnamespace/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("example", namespace);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("Login", "example");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("username", "example");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("password", "example");
soapBodyElem1.addTextNode("email#example.com");
soapBodyElem2.addTextNode("1234");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", namespace + "Login");
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
}
with this java webservice method
#WebMethod(operationName="Login")
public boolean Login(#WebParam(name = "username") String username,
#WebParam(name = "password") String password) {
System.out.print(username + "-" + password);
}
but username and password are always null so the output when the method is called is "null-null", I would like to know how call this method sending the paramaters correctly.
thanks!
You can make a HTTPClient call and pass SOAP request as string parameter.
There are better way to do this that internally does the above for example using Apache AXIS2, CXF, JAX-WS etc.
I prefer to use CXF by generating stubs of WSDL file and calling the service through JAVA.
Refer examples:
https://rathinasaba.wordpress.com/2013/02/01/call-webservice-wsdl-based-using-apache-httpconnection/
How to call a SOAP webservice with a simple String (xml in string format)
I wrote method, which generate soap message from java string:
private SOAPMessage createRequest(String msg) {
SOAPMessage request = null;
try {
MessageFactory msgFactory = MessageFactory.newInstance();
request = factory.createMessage();
SOAPPart msgPart = request.getSOAPPart();
SOAPEnvelope envelope = msgPart.getEnvelope();
SOAPBody body = envelope.getBody();
StreamSource _msg = new StreamSource(new StringReader(msg));
msgPart.setContent(_msg);
request.saveChanges();
} catch(Exception ex) {
ex.printStackTrace();
}
}
And, after that, I try generate some message. For example:
createRequest("test message");
But here - request.saveChanges(); I catch this exception:
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Error during saving a multipart message
Where is my mistake?
That is because you are not passing a correct protocol formatted message.
Your code doesn't specify which SOAP protocol you want to use, that means it creates a message factory for SOAP 1.1 messages.
Thus, you would need to pass a correct SOAP1.1 message.
I replicated your method like this:
private static SOAPMessage createRequest(String msg) {
SOAPMessage request = null;
try {
MessageFactory msgFactory = MessageFactory
.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
request = msgFactory.createMessage();
SOAPPart msgPart = request.getSOAPPart();
SOAPEnvelope envelope = msgPart.getEnvelope();
SOAPBody body = envelope.getBody();
javax.xml.transform.stream.StreamSource _msg = new javax.xml.transform.stream.StreamSource(
new java.io.StringReader(msg));
msgPart.setContent(_msg);
request.saveChanges();
} catch (Exception ex) {
ex.printStackTrace();
}
return request;
}
and I call it using this string:
String soapMessageString = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body></SOAP-ENV:Body></SOAP-ENV:Envelope>";
createRequest(soapMessageString);
and It works.
Sample Webservice Mehtod
public String getMsg(String arg1,String arg2)
{
System.out.println("arg1--->"+arg1);
System.out.println("arg2--->"+arg2);
return "response";
}
Client Code
private static SOAPMessage createSOAPRequest() throws Exception
{
System.out.println("createSOAPRequest---->");
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://webservice.jaipal.econnectsolution.com";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("MineralWebService", serverURI);
//SOAP Body
SOAPBody soapBody = envelope.getBody();
System.out.println("soapBody----->"+soapBody);
SOAPElement soapBodyElem = soapBody.addChildElement("getMsg", "MineralWebService",serverURI);
SOAPElement value = soapBodyElem.addChildElement("getMsg","MineralWebService");
value.setTextContent("Arguments One");
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "add");
System.out.println("headers----->"+headers.toString());
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
I want To add wwo arguments to call my webservice mehtod. Using above code, I was Able to send only one Argument.
Please help me to achieve this.
Have you tried creating/adding new element, like you are doing it for first argument?
SOAPElement soapBodyElem2 = soapBody.addChildElement("getMsg", "MineralWebService",serverURI);
SOAPElement value2 = soapBodyElem2.addChildElement("getMsg","MineralWebService");
value2.setTextContent("Arguments Two");
I implemented a soap client to call a web service method of a third person. The method is: InsertData_Str
I've a problem with my java application. I need to add to the InsertData_Str method the xmlns attribute but it doesn't work, it put an empty value and I don't understand why. Any idea?
Here is the code:
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
soapMessage.setContentDescription("MY Connector");
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "http://www.ik.com/ikConnect";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.setPrefix("soap");
SOAPBody soapBody = envelope.getBody();
SOAPElement soapMethod = soapBody.addChildElement("InsertData_Str"); //Method
//soapMethod.setAttribute("xmlns", "http://www.ik.com/ikConnect"); //This doesn't work
QName attributeName = new QName("xmlns");
soapMethod.addAttribute(attributeName,"http://www.ik.com/ikConnect"); //If I Debugg I can see that xmln attribute is OK but when the message is sent xmln is empty
Here is the output:
<?xml version="1.0" encoding="utf-8" ?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><InsertData_Str xmlns=""><xdoc xmlns="http://www.ik.com/ikConnect">TEST</xdoc></InsertData_Str></SOAP-ENV:Body></soap:Envelope>
I solved it.
I changed SOAPElement addChildElement(String localName) method by this other one addChildElement(String localName,String prefix,String uri)
Example:
String serverURI = "http://www.ik.com/ikConnect";
SOAPElement soapMethod = soapBody.addChildElement("InsertData_Str", "", serverURI);