Using JAX-WS and a custom WSDL, is there a way to get the message that would be sent to a web-service without actually making a call to the service? I need to generate a soap message conforming to a WSDL, but that soap message is actually embedded into another message. I was thinking I could create a local web-service that just echos back the message but it seems like there should be a way without doing this or using a handlerchain when it doens't really matter that the message is sent.
Maybe the easiest thing to do is just to generate the soap manually?
I hope this helps:
http://www.java-tips.org/java-ee-tips/java-api-for-xml-web-services/writing-a-handler-in-jax-ws.html
You can intercept message before being sent, get the body, get the header, sign it with SAML or whatever you want, and then send it to server.
maybe this example helps (from Understanding Web Services, Part 1: SOAP, IBM Developer Works, page 21):
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
SOAPPart SOAPPart = message.getSOAPPart();
SOAPEnvelope envelope = SOAPPart.getEnvelope();
SOAPBody body = envelope.getBody();
SOAPElement bodyElement = body.addChildElement(envelope.createName("echo", "req", "http://localhost:8080/axis2/services/MyService/"));
bodyElement.addChildElement("category").addTextNode("classifieds");
message.saveChanges();
SOAPPart SOAPpartbefore = message.getSOAPPart();
SOAPEnvelope reqenv = SOAPpartbefore.getEnvelope();
System.out.println(reqenv.toString());
Related
I am new to all of this but I am trying to create a SOAP message and get stuck at the off, I am using Java 8 and the standard javax.xml.soap classes but seem unable to add namespaces to the Envelope
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPPart part = message.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
envelope.addNamespaceDeclaration( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
If I try this at runtime I get the following error
NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
I have done this now by creating the required envelope definition as an XML String and then setting the SOAPPart content using that string
I'm creating a SOAPMessage object, and before I send it I want to encrypt the contents. I'm creating it in a similar way to many examples that can be found on SO, for example:
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
// Retrieve different parts
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
// Two ways to extract body
SOAPBody soapBody = soapEnvelope.getBody();
soapBody = soapMessage.getSOAPBody();
//Modify body
// Etc
I can't find examples of how to encrypt the contents of an object that I create like this.
Soap Encryption is different from normal encryption process we do, as Encrypted XML payload has to be in a standard structure specified by WS-Security.
Use any WS-Security implementation like Axis, WSS4J.
I am having one function where we generate SOAP request.The request I am able to run in SOAP UI tool and its fetching.
I am creating SOAPMessage like this
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.removeAllHeaders();
headers.addHeader("Content-Type", "text/xml");
SOAPPart soapPart = soapMessage.getSOAPPart();
When I call
SOAPMessage soapResponse = soapConnection.call(soapMessage, url);
get this error:
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
could you help to sort it out?
whether that means connection unable to establish??
Most probably expected HTTP Content-Type header for SOAP messages is application/soap+xml (see XML SOAP).
The exception you get originates from SOAP service container saying that the value of Content-Type header is text/html. I think that SOAP UI set the correct request header value for you.
The header value sent by your code seem to be a default one. You should check what the expected Content-Type value is for you server and ho to set it with your framework/library.
I am trying to write a SOAP pull. I am running into difficulty formatting the message correctly.
I am only using the included javax.xml.soap.* library with Exclipse
I need the Envelope to have multiple URIs in it. This is the example provided for use with SOAPUI.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sh="http://www.website.com/ems/soap/sh" xmlns:user="http://www.website.com/ems/soap/sh/userdata" xmlns:ser="http://www.website.com/ems/soap/sh/servicedata">
However after looking through several tutorials I am only able to produce
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sh="http://www.website.com/ems/soap/sh">
I have haven't been able to find any documentation on how to achieve the required output. I am still new to SOAP and Java so I am not sure how to articulate exactly what I need.
Here is the code I have so far minus the child element portion
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
soapMessage.getSOAPPart().getEnvelope().setPrefix("soapenv");
soapMessage.getSOAPPart().getEnvelope().removeNamespaceDeclaration("SOAP-ENV");
soapMessage.getSOAPBody().setPrefix("soapenv");
soapMessage.getSOAPHeader().setPrefix("soapenv");
String serverURI = "http://www.website.com/ems/soap/sh";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("sh", serverURI );
If you want to get this soap-envelope,
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sh="http://www.website.com/ems/soap/sh" xmlns:user="http://www.website.com/ems/soap/sh/userdata" xmlns:ser="http://www.website.com/ems/soap/sh/servicedata">
Just add addNamespaceDeclaration after your code like this.
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("sh", serverURI );
//added code here
envelope.addNamespaceDeclaration("user", "http://www.website.com/ems/soap/sh/userdata" );
envelope.addNamespaceDeclaration("ser", "http://www.website.com/ems/soap/sh/servicedata" );
I'm using CXf's fault out interceptor to intercept the exception from the web services method. That works fine within the handleMessage method..
Now I have two questions,
How do I had extra information to the Fault object apart from setting the faultcode?
Say if there is any error in the handleMessage method, the control goes to handleFault method but in the handle fault method it simply unwinds and logs something like - GetMth has thrown exception, unwinding now: java.lang.Exception. But the fault message(in xml format) is not being sent to the client as Output mesasage,
2. How do I make sure that the fault message is sent as SOAPfault to the clinet? (in the hanldeMessage below, i have place `f=null` to introduce the fault) Please Suggest!!!
I managed to write the xml content to the writer class with the below code, but am unable to pass this message to the client. I mean even after writing the message to the xmlwriter class and content being written fine to the console log, its not been sent to the client. i.e, I dont see the outbound message being sent nor printed when i turn on the monitors and the interceptor outbound logs. Could anyone please help me with this?
MessageFactory factory = getFactory(message);
SOAPMessage soapMessage = factory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPBody soapBody = soapPart.getEnvelope().getBody();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultString("Strange");
W3CDOMStreamWriter writer1 = new SAAJStreamWriter(soapPart);
message.setContent(XMLStreamWriter.class, writer1);
message.setContent(SOAPMessage.class, soapMessage);
message.setContent(Node.class, soapMessage.getSOAPPart());
message.getInterceptorChain().add(SAAJOutEndingInterceptor.INSTANCE);
LOGS:
saaj the factory com.sun.xml.messaging.saaj.soap.ver1_2.SOAPMessageFactory1_2Impl#146ee9c
saaj the soapMessage com.sun.xml.messaging.saaj.soap.ver1_2.Message1_2Impl#1db52c8
saaj the soapPart com.sun.xml.messaging.saaj.soap.ver1_2.SOAPPart1_2Impl#17d6c1
saaj the soapsoapBodyPart [env:Body: null]
saaj the soapFault [env:Fault: null]
saaj the setFaultString Strange
saaj the messg {org.apache.cxf.message.Message.RESPONSE_CODE=200, HTTP.RESPONSE=org.apache.catalina.connector.ResponseFacade#2982bf, org.apache.cxf.headers.Header.list=[], wrote.envelope.start=true, org.apache.cxf.message.Message.ENCODING=UTF-8, org.apache.cxf.message.FaultMode=CHECKED_APPLICATION_FAULT, org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap12#b16f5f, Content-Type=application/soap+xml, org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor.original.xml.writer=[StreamWriter: class com.ctc.wstx.sw.SimpleNsStreamWriter, underlying outputter: com.ctc.wstx.sw.BufferingXmlWriter#1144823], org.apache.cxf.interceptor.LoggingOutInterceptor.log-setup=true, org.apache.cxf.service.model.BindingFaultInfo=org.apache.cxf.service.model.BindingFaultInfo#106def2}
saaj the writer1 :
><pre><env:Header/><env:Body><env:Fault><env:Code><env:Value>env:Receiver</env:Value></env:Code><env:Reason><env:Text xml:lang="en-US">Strange</env:Text></env:Reason></env:Fault></env:Body> </pre>
Please advise.