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.
Related
I have created a basic CRUD API using Dropwizard and Spring. In the body of my response object, I am receiving the following:
)]}',
{
"id":10,
"initiator":2,
"target":1,
"statusId":1,
"created":"2018-04-30T14:45:01.173"
}
I checked the API using curl, postman, and programatically during testing with rest assured, and the invalid characters )]}', are always present. Postman seems to be capable of ignoring them and displaying a pretty printed output, however rest assured, and I'm guessing most JSON parsers, can't parse it correctly.
Questions:
What are they?
Why are they present?
How do I remove them?
I've been writing REST APIs for years and I've never seen anything like this. This is my first time using dropwizard so I'm optimistically hoping it is some configuration I have missed.
Apart from the the invalid characters, functionally the API works fine.
This is an inherited codebase, and other APIs return these characters also. For the purposes of testing in rest assured the invalid characters are filtered out before processing the response. While this seems acceptable to me as a workaround in the short term, long term any future consumers of the API will all have to perform the workaround, and ideally this would be fixed in the API itself.
Not aware of DropWizard but it is there to prevent json-hijacking.
In Spring there is a MappingJackson2HttpMessageConverter class.
which has same feature, but prefix is different "{} &&"
/**
* Indicate whether the JSON output by this view should be prefixed with "{} &&". Default is false.
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed on the
* string, the prefix would need to be ignored.
*/
public void setPrefixJson(boolean prefixJson) {
this.prefixJson = prefixJson;
}
You can relate to this.
Edit 1:
Spring version 4.2.0.RELEASE onwards, default prefix has been updated to )]}',
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.
I am re-wording my question because the 'parsed entity' thing has nothing to do with the problem at hand.
XML 1.1 versus 1.0
Is an xml 1.1 library is to escape illegal characters before serializing/deserializing them? Or is the library is to forbid them outright? Which is the correct way to set Text on an xml element?
if Element e = new Element("foo")
Should I do this:
e.setText(sanitized_text_illegal_characters_removed_or_escaped) ?
or
e.setText(any_text)
A parsed entity is something you don't really need to worry about unless you're writing an XML parser. It's things like < and &. You can define your own in the document DTD, but it's a rarely used feature. An external parsed entity is one whose contents reside in another file or network resource or somewhere like that.
As to your main question:
Which is the correct way to set Text on an xml element?
if Element e = new Element("foo")
Should I do this:
e.setText(string_of_sanitized_data_with_illegal_characters_escaped) ?
or
e.setText(any_text)
You should set the text as you would like it to come out the other end, when the document is deserialized. This normally means you should not escape the data, and the XML library will do this for you.
e.g.:
You insert the text "bed & breakfast".
The XML library converts this to "bed & breakfast" or "<![CDATA[bed & breakfast]]>" or some other representation, it doesn't really matter.
You send the document somewhere else.
The other parser reads the document and converts the text back.
The end software retrieves the string "bed & breakfast".
If you're writing XML programmatically, then you almost certainly don't want to use parsed entities.
There are two kinds of parsed entities: internal and external. An internal parsed entity is defined by a DTD declaration like this:
<!ENTITY me "Mike">
or
<!ENTITY me "<name>Mike</name>">
An external parsed entity is defined by a DTD declaration like this:
<!ENTITY me SYSTEM "me.xml">
Whether the entity is internal or external, it can be referenced by an entity reference like this:
&me;
which can appear within the content of an element or attribute.
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
In my Scala code, I am fetching a response from a server using the getInputStream method of HttpUrlConnection class. The response is XML data. However the data contains HTML entities like & and '.
Is there a way I can replace these characters with their text equivalent so that I can parse the XML properly?
It's necessary to encode those entities in xml so they don't interfere with its syntax. The <(<) and > (>) entities make this more obvious. It would be impossible to parse XML whose content was littered with < and > symbols.
Scala's scala.xml package should give you the tools you need to parse your xml. Here's some guidance from the library's author.