In Java, I need to add a SOAP header containing authentication data for a client-side SOAP request to a 3rd party web service that I have no control over. I have set up a SOAPHandler, and am monitoring the actual code sent to the server-side to see what is going on. The authentication is not working.
What I precisely need is:
<soap12:Header>
<AuthenticationHeader xmlns="http://abc.xyz.com/">
<UserName>uname</UserName>
<Password>pwd</Password>
</AuthenticationHeader>
</soap12:Header>
I can create the AuthenticationHeader element and add it with the SOAPHeader.addHeaderElement method without issue, but I can't get the username and password content added properly. What I can get from using the various commands to set the text for a SOAPElement (setValue, setTextContent, addTextNode), and then using SOAPHeaderElement.addChildElement is
<soap12:Header>
<AuthenticationHeader xmlns="http://abc.xyz.com/">
<UserName xmlns="">uname</UserName>
<Password xmlns="">pwd</Password>
</AuthenticationHeader>
</soap12:Header>
The server side can't cope with the extra xmlns="" that all the commands I have tried seem to add to the UserName and Password tag names.
If I try to construct a string and add that text directly to the AutheticationHeader element, the < and > characters are escaped. I've also tried CDATA tags...that prevents escaping of the < and > characters, but the server still doesn't like it.
I found a solution constructing a Document to hold the raw text (which prevents escaping the characters), and then adding that, but unfortunately, it seems that Document can only be added to the SOAP body, not the SOAP header.
Does anyone have any suggestions how to overcome this? The server people are programming in .NET, not Java, so they aren't able to help.
I am getting the proper response back from the server, with all off the correct SOAP output tags, but the error message contained in the tag is "Can't Authenticate".
Thanks!
Following code will generate the correct Authentication Header that you would like to generate.
SOAPHeader header = request.getSOAPHeader();
Document doc = header.getOwnerDocument();
Element el1 = doc.createElementNS("http://abc.xyz.com/","UserName");
el1.setTextContent("MyName");
Element el2 = doc.createElementNS("http://abc.xyz.com/","Password");
el2.setTextContent("pass******");
Element el0 = doc.createElementNS("http://abc.xyz.com/", "AuthenticationHeader");
el0.appendChild(el1);
el0.appendChild(el2);
header.appendChild(el0);
Related
I'm using Java to call a remote webservice, sometimes it sends me a reply that is a "valid" XML but without header, like this:
<Re>
<Re1>
<code>108</code>
<desc>Error.</desc>
<det>Imposible ejecutar</det>
</Re1>
</Re>
Due to the lack of header I cannot process it, so I'm thinking to add header myself, but before I want to check if it's a valid XML or only garbage.
How can I do that?
I am a beginner in programming so please bear with my lack of knowledge.
I am working on sending and receiving a soap request via HttpsURLConnection. The problem is, the reply from the input stream has namespace declarations and the application does not recognize these.
I take the result from the input stream as text:
def reply = bufferedReader.getText()
but I can also create a Soap Message:
reply = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL).createMessage(null, conn.getInputStream())
Both methods still give namespace prefix. But I'm not sure if I've missed something. I can manipulate both XML and SoapMessage so any pointers will help.
When I send a request using SoapConnection.connect(), the XML file doesn't contain the prefix. However, when I use HttpsURLConnection, I get these. I cannot use SoapConnection.connect() for other reasons though.
I have been struggling for many hours. Any help is appreciated. Please ask if you need more info.
Thanks,
so currently I'm retrieving the data from a url using the following code
Document doc = Jsoup.connect(url).get();
Before I fetch the data I've decided I want to get the content type, so I do that using the following.
Connection.Response res = Jsoup.connect(url).timeout(10*1000).execute();
String contentType = res.contentType();
Now I'm wondering, is this making 2 separate connections? Is this not efficient? Is there a way for me to get the content type and the document data in 1 single connection?
Thanks
Yes Jsoup.connect(url).get() and Jsoup.connect(url).timeout(10*1000).execute(); are two separate connections. Maybe you are looking for something like
Response resp = Jsoup.connect(url).timeout(10*1000).execute();
String contentType = res.contentType();
and later parse body of response as a Document
Document doc = resp.parse();
Anyway Jsoup by default parses only text/*, application/xml, or application/xhtml+xml and if content type is other, like application/pdf it will throw UnsupportedMimeTypeException so you shouldn't be worried about it.
Without looking at the Jsoup internals we can't know. Typically when you want to obtain just the headers of a file (the content type in your case) without downloading the actual file content, you use the HTTP GET method instead of the GET method to the same url. Perhaps the Jsoup API allows you to set the method, that code doesn't seem like it's doing it so I'd wager it's actually getting the entire file.
The HTTP spec allows clients to reuse the connection later, they are called HTTP persistent connections, and it avoids having to create a connection for each call to the same server. However it's up to the client, Jsoup in this case since you aren't handling the connections in your code, to make sure it's not closing the connections after each request.
I believe that the overhead of creating two connections is offset by not downloading the entire file if you're code decides that it shouldn't download the file if it's not of the content type that you want.
Is there a way to retrieve the full SOAP message to handle it (envelope and all) when using the javax.xml.soap.SOAPMessage class?
I am using JMX-WS and want to edit the outbound SOAP Message from the server, in order to append two characters to the message AFTER the end closing tag of the envelope, as the client legacy code is expecting it. So ideally I would like to be able to edit the full message as a String, is this possible?
You can do this with cxf :
http://www.mastertheboss.com/web-interfaces/337-apache-cxf-interceptors.html
Take a look at the LogInterceptor example
Im working with a server which always sends me XML responds. But sometimes when server is lack or something it reports me about it by sending me back a HTML page (it just a html page informing about the error) but i didn't expect that and my XML parser crashed.
Im using DefaultHttpClient() and I do send header like mHttpRequest.setHeader("Accept", "text/xml");
So what is the proper way to ensure i got XML (or other specific format) response?
As Kristian suggested, see if it provides a different Content-Type when HTML is emitted. Failing that I would check for a <?xml... line, as apposed to a doctype or whatever is on the HTML page.
Can you check the content type header on the response?
Something like (if I understand the Android documentation correctly):
"text/xml".equals(httpResponse.getEntity().getContentType().getValue());
Every XML contains document descriptor <?xml version="1.0" encoding="utf-8"?> in the beginning. You can check for this before parsing it.
However, I think you need some error handling and result validation in your parser. Network is not a safe environment - you can easily get a half-broken, malformed, or even forged XML from the network. Good parser should detect that and report corresponding errors, not just crash.