Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with invalid characters in a WS output when using CXF?

Tags:

java

spring

xml

cxf

I'm using Spring, CXF and Hibernate to build a WebService that perform search queries on a foreign database that I have read-only access.

The problem is that some entries in the database have strange characters (0x2) in text fields, and it seems that CXF or the library (Aegis?) that it uses to process/serialize the objects returned from the Hibernate session can't deal with it:

org.apache.cxf.aegis.DatabindingException: Error writing document.. Nested exception is com.ctc.wstx.exc.WstxIOException: Invalid white space character (0x2) in text to output (in xml 1.1, could output as a character entity)

How do I get around that? Ideally, I could just remove those characters, since they don't matter for my output... Thanks!

like image 740
Elias Dorneles Avatar asked Mar 14 '12 21:03

Elias Dorneles


3 Answers

/**
* From xml spec valid chars:<br>
* #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]<br>
* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.<br>
* @param text The String to clean
* @param replacement The string to be substituted for each match
* @return The resulting String
*/
public static String CleanInvalidXmlChars(String text, String replacement) {
    String re = "[^\u0009\r\n\u0020-\uD7FF\uE000-\uFFFD\uD800\uDC00-\uDBFF\uDFFF]";
    return text.replaceAll(re, replacement);
}

source: http://www.theplancollection.com/house-plan-related-articles/hexadecimal-value-invalid-characterheplancollection.com/house-plan-related-articles/hexadecimal-value-invalid-character

like image 158
nDijax Avatar answered Nov 16 '22 10:11

nDijax


I am not sure this answers your question, but here is what I found.

Here is the class that throws the exception: http://svn.codehaus.org/woodstox/wstx/trunk/src/java/com/ctc/wstx/api/InvalidCharHandler.java

Seems like there is a discussion on the issue here: http://comments.gmane.org/gmane.comp.apache.cxf.user/4373

Maybe this might can you: You can also set a "disable.outputstream.optimization" property on the endpoint/bus to true to have it disable the direct writing to the outputstream and always go through the XMLStreamWriter. Should accomplish the same thing without the overhead of having the SAAJModel created.

Hope this helps a bit.

like image 35
Jarle Hansen Avatar answered Nov 16 '22 09:11

Jarle Hansen


To achieve the desired behaviour and avoid exceptions being thrown, you'll have to extend the default Woodstoks factory com.ctc.wstx.stax.WstxOutputFactory with your own's, that's supposed only to overwrite the property com.ctc.wstx.outputInvalidCharHandler with an instance of com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler. This handler takes as constructor argument the replacement char to the invalid ones. With your instance in hand, create a file named META-INF/services/javax.xml.stream.XMLOutputFactory and place inside it only the complete name of your implementation (make sure it'll be placed inside the META-INF/services directory in the resulting jar).

You can find more details here.

HTH!

like image 2
cristianoms Avatar answered Nov 16 '22 09:11

cristianoms