SAAJ request xml , envelope prefix changes itself - java

I am facing a problem, where my request xml , which I build using SAAJ has a Envelope prefix as SOAP-ENV:Envelope when I run it in eclipse main method. Whereas when I put the code in the Weblogic 11g I checked the prefix has become env:Envelope. The Envelope xml I was using is "http://schemas.xmlsoap.org/soap/envelope/".
I will be glad if anyone tell me what is happening, and what the effect is if I send the request with either of the prefix?

The prefix should not matter, as long as it references the right uri in the namespace declaration. However... There are nitwits, no-nos, or whatever you like to call them, that implement things in a wrong way (manually parse the xml) and expect a specific prefix.

Related

JAX-WS CXF empty XOP multipart attachments with file size > ~210kb

I am using jax-ws cxf to load documents from a SOAP interface. I can get the correct document via SoapUI (xop/multipart). Unfortunately, when I try to load the attachment via code, the CachedOutputStream is empty for files greater than ~210kb.
What I tried:
Activate MTOMFeature for my WebServiceClient
Play with JVM arguments CachedOutputStream.Threshold and CachedOutputStream.MaxSize
Use different versions of apache-cxf (3.2.1 or 3.1.14)
When debugging:
PhaseInterceptorChain#doIntercept uses the AttachmentInInterceptor (at currentInterceptor.handleMessage(message);) which loads the attachments with LazyAttachmentCollection and adds it to the message.
happy case: document is loaded into CachedOutputStream and available after the for-loop.
error case (file too big?): document is available directly after currentInterceptor.handleMessage is called, but disappears when the loop has finished
In both of the above cases however, a correct tmp file is saved to my disk (with exactly my document's content). Furthermore, I can load that file in both cases even when the loop has finished with: ((org.apache.cxf.attachment.LazyAttachmentCollection)(message.getAttachments())).loadAll();
I had similar problem with apache-cxf 3.1.6. The issue was that files above 102kB were empty. After some digging it turned turned out to be "attachment-memory-threshold" which u can set in requestContext, for some reason file cache doesnt seem to work.

How can I use XPath to resolve the following 'tags' values?

The xml file is :
<xml-fragment xmlns:xyz="http://someurl">
<xyz:xyzcontent>
<contentattribute>
<key>tags</key>
<value>tag1, tag2</value>
</contentattribute>
</xyz:xyzcontent>
...
I've tried the following:
XPathExpression createdDateExpression = xpath.compile("/contentattribute/key/attribute::tags/value");
There are several problems with your query.
The XML is broken (root tag not closed) -- probably just a copy/paste mistake
You're starting somewhere right in the middle of the XML tree, but actually try to query from the root node. Use the descendant-or-self-axis // in the beginning.
Which attribute are you querying using the attribute-axis? There is none.
Where did you register the namespaces? What namespace is xyz, anyway? I guess it's actually vp, but you obfuscated incompletely (or are not giving all relevant parts of the document).
Use predicates and string comparison to filter at axis steps.
Try following:
Make sure to register the namespace, have a look at the reference for that (or give more information).
Use the XPath query //contentattribute[key='tags']/value

Manipulate soap message as a string

Is it possible to manipulate a SOAP message generated by Jax-WS as a String before sending it to the server? I would like to intercept the message exactly before it's going to be sent and modify some tags.
I want to do this because I need to send a SOAP request to the server. A tag of this request has a lot of xml documents as its content. For each document I need to redeclare the namespace in some tags (Jax-WS intelligently declare it just once). I can't use any prefixes. I need to sign the xml too. All these problems would be easier to solve if I could manipulate the message as a string.
I've seen something similar with axis, but I didn't find out how to do this with Jax-WS.
Thank you.
Update: I already have tried to use handlers (both SOAP and Logical handlers). My problem is that the message is changed by Jax-WS even after I modify it with the handlers. The body of my soap message needs to look like this:
<soap12:Body>
<cteDadosMsg xmlns="http://www.portalfiscal.inf.br/cte/wsdl/CteRecepcao">
<enviCTe xmlns="http://www.portalfiscal.inf.br/cte" versao="1.04">
<idLote>1</idLote>
<CTe xmlns="http://www.portalfiscal.inf.br/cte">
</CTe>
<CTe xmlns="http://www.portalfiscal.inf.br/cte">
</CTe>
</enviCTe>
</cteDadosMsg>
</soap12:Body>
Look that my CTe tags need to repeat the namespace declaration (the same used by enviCTe). I tried to do the following steps:
1) Created the document containing the enviCTe using Jaxb.
2) Converted it to string and adjusted the namespace declaration of the CTe tags (using String.replace).
3) Added the xml string to the cteDadosMsg. Jax-WS escapes the characters (replacing < for < for example). The web service does not understand the xml with the escaped characters.
4) Added a LogicalHandler for unescaping the payload (replacing < for < and so on).
5) After doing this, Jax-WS adjusts the namespace declaration again and the xmlns attribute of my CTe tags disappear. :P That's my problem. Jax-WS "fix" the message even after modifying it with the handlers.
Instead of adding the xml generated by Jaxb as a string, I also tried to add it as a Document. I don't have the problems with escaping, but I still can't repeat the namespace declaration for every CTe tag.
When I solve this, I still will have to sign some tags of the xml. So I really would like to intercept the message just before it is sent and modify it as a string.
Am I missing something?
You can do the same using Handlers. Refer here for more details.

Reading XML data between tags

I have a XML for which i am writing a servlet to pick up contents from the XML. One such tag is <itunes:author>Jonathan Kendrick</itunes:author>
I need to get author value for this. because of :
I tried using namespace and using escape sequence for : but it did not worked for me.
For rest of other XML elements i am simply using
String link=node.getChildText("link").toString();
I am using Jdom parser
in your XML the sequernce 'itunes:author' represents what's called a Q-Namem a "Qualified Name". In XML it consists of a 'Namespace prefix', and a 'Local Name'. In your example, the namespace prefix is 'itunes', and the 'local name' is 'author'.
What you want is the 'author' element in the namespace linked to the prefix 'itunes'. The actual namespace is normally a full URL. I believe the full URL for your example is probably xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd", but you should check that.
So, the Namespace is "http://www.itunes.com/dtds/podcast-1.0.dtd", it's prefix is declared to be 'itunes' (but it could be something else - the actual prefix name is not technically important...)
You want to get the 'author' in the 'http://www.itunes.com/dtds/podcast-1.0.dtd' Namespace so you want:
String author = node.getChildText("author", Namespace.getNamespace("http://www.itunes.com/dtds/podcast-1.0.dtd"));
For more information on Namespaces check out: http://www.w3schools.com/xml/xml_namespaces.asp

Using XPath in XMLObject to query by namespace

I have a simple XML document
<abc:MyForm xmlns:abc='http://myform.com'>
<abc:Forms>
<def:Form1 xmlns:def='http://decform.com'>
....
</def:Form1>
<ghi:Form2 xmlns:ghi='http://ghiform.com'>
....
</ghi:Form2>
</abc:Forms>
</abc:MyForm>
I'm using XMLObjects from Apache and when I try to do the following xpath expression it works perfectly
object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms/*");
this gives me the 2 Form nodes (def and ghi). However I want to be able to query by specifying a namespace, so let's say I only want Form2. I've tried this and it fails
object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms/*
[namespace-uri() = 'http://ghiform.com']");
The selectPath returns 0 nodes. Does anyone know what is going on?
Update:
If I do the following in 2 steps, then I can get the result that I want.
XmlObject forms = object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms")[0];
forms.selectPath("*[namespace-uri() = 'http://ghiform.com']");
this gives me the ghi:Form node just like it should, I don't understand why it doesn't do it as a single XPath expression though.
Thanks
The simple answer is that you can't. The namespace prefix is just a shorthand for the namespace URI, which is all that matters.
For a namespace-aware parser, your two tags are identical.
If you really want to differentiate using the prefix (although you really, really shouldn't be doing it), you can use a non namespace-aware parser and just treat the prefix as if it was part of the element name.
But ideally you should read a tutorial on how namespaces work and try to use them as they were designed to be used.

Categories