Search code examples
javaxmljacksonescapingjackson-dataformat-xml

Escaping quotes using jackson-dataformat-xml


I need help with jackson-dataformat-xml. I need to serialize List<String> using XmlMapper into the xml with encoding the quotes "&quot;.

But after serializing XmlMapper encodes all other special symbols (<, >, & etc) but ignores quotes (' and ") at all... If I encode the string manually before serialization, the content messes up because &quot; has '&' inside and it's serializing as &amp;quot; instead of course.

Maybe anyone knows how to make it work? Also, is there a way as work-around to disable auto special symbols encoding on the List<String> field using @JacksonRawValue or something like that? This annotation works great on simple (non-arrays) fields but not gonna work properly on List<String>.

Thanks.


Solution

  • Here's how the problem was solved. I used woodbox Stax2 extension. This helped a lot. https://github.com/FasterXML/jackson-dataformat-xml/issues/75

    XmlMapper xmlMapper = new XmlMapper(module);
    xmlMapper.getFactory().getXMLOutputFactory().setProperty(XMLOutputFactory2.P_TEXT_ESCAPER, 
    new CustomXmlEscapingWriterFactory());
    

    And here's the factory.

    public class CustomXmlEscapingWriterFactory implements EscapingWriterFactory {
    public Writer createEscapingWriterFor(final Writer out, String enc) {
        return new Writer(){
            @Override
            public void write(char[] cbuf, int off, int len) throws IOException {
                String val = "";
                for (int i = off; i < len; i++) {
                    val += cbuf[i];
                }
                String escapedStr =  StringEscapeUtils.escapeXml(val);
                out.write(escapedStr);
            }
    
            @Override
            public void flush() throws IOException {
                out.flush();
            }
    
            @Override
            public void close() throws IOException {
                out.close();
            }
          };
        }
    
        public Writer createEscapingWriterFor(OutputStream out, String enc) {
            throw new IllegalArgumentException("not supported");
        }
    }