xml output

1,689 views
Skip to first unread message

Jeffrey Brekke

unread,
Jun 3, 2012, 12:53:41 AM6/3/12
to dropwiz...@googlegroups.com
I know drop wizard is slanted toward json output, but I am replacing a service with a drop wizard implemented version and need both xml and json responses.  Jersey supports xml, but I cannot get drop wizard to output xml versions of the model classes, json works.  A 500 status code is returned, but setting the logs to DEBUG show no stack trace.  The service is simple and I can see in the logs that the service and dao are executing given an Accept: header of application/xml so it is being routed correctly I believe.  Any pointers?

Arul Dhesiaseelan

unread,
Jun 3, 2012, 2:40:25 AM6/3/12
to dropwiz...@googlegroups.com
I believe you may want to add JAXB annotation @XmlRootElement to your model and perform negotiation using Accept headers.

Tatu Saloranta

unread,
Jun 3, 2012, 10:30:50 PM6/3/12
to dropwiz...@googlegroups.com
On Sat, Jun 2, 2012 at 11:40 PM, Arul Dhesiaseelan <ar...@acm.org> wrote:
> I believe you may want to add JAXB annotation @XmlRootElement to your model
> and perform negotiation using Accept headers.

Another alternative is to use Jackson's XML output module
(https://github.com/FasterXML/jackson-dataformat-xml) for
serialization, and get it registered as JAX-RS provider using
(https://github.com/FasterXML/jackson-jaxrs-xml-provider) for
DropWizard/Jersey to use it.
This does not require @XmlRootElement, and can use the same
annotations Jackson uses for JSON (and/or JAXB annotations via JAXB
module).

While JAXB is more powerful for producing XML (in areas of XML Schema
support and exotic XML features), Jackson XML module has more powerful
data binding features, same as standard JSON part has. So it may be
worth investigating.

-+ Tatu +-

Paul Philion

unread,
Jul 15, 2013, 5:10:54 PM7/15/13
to dropwiz...@googlegroups.com
Tatu,

In context of DropWizard, how does one register a custom XML serializer (I assume an implementation of XmlAdapter) with Jersey. I have not been able to get the custom implementation I wrote be used. Specifically I'm trying to serialize generic Maps to XML. Standard POJO entities work fine.

Tatu Saloranta

unread,
Jul 15, 2013, 5:29:01 PM7/15/13
to dropwiz...@googlegroups.com
On Mon, Jul 15, 2013 at 2:10 PM, Paul Philion <phi...@gmail.com> wrote:
Tatu,

In context of DropWizard, how does one register a custom XML serializer (I assume an implementation of XmlAdapter) with Jersey. I have not been able to get the custom implementation I wrote be used. Specifically I'm trying to serialize generic Maps to XML. Standard POJO entities work fine.



I think XML side defaults to using JAXB, and with JAXB XmlAdapter is the way; using JAXB annotations to indicate dependencies.
But trying to make generic Maps work with XML may be an exercise in futility -- at least they will not work (nor do Lists) well as root values; similarly Maps of Maps, Lists of Lists, or combinations thereof do not work well.
You can avoid these issues by intermediate POJOs (POJO->Map<String,POJO2>, where POJO2 can contain Maps, Lists).
I don't know if/how DropWizard allows customizing JAXB setup.

JAXB should work out of the box via Jersey.

Jackson XML module can also use XmlAdapter route (when making use of JAXB annotations); but preferably you would use Jackson custom (de)serializers and other annotations.
One benefit is that Java Maps and List (Collections) are supported without requiring adapters.

-+ Tatu +-

 
On Sunday, June 3, 2012 7:30:50 PM UTC-7, Tatu Saloranta wrote:
On Sat, Jun 2, 2012 at 11:40 PM, Arul Dhesiaseelan <ar...@acm.org> wrote:
> I believe you may want to add JAXB annotation @XmlRootElement to your model
> and perform negotiation using Accept headers.

Another alternative is to use Jackson's XML output module
(https://github.com/FasterXML/jackson-dataformat-xml) for
serialization, and get it registered as JAX-RS provider using
(https://github.com/FasterXML/jackson-jaxrs-xml-provider) for
DropWizard/Jersey to use it.
This does not require @XmlRootElement, and can use the same
annotations Jackson uses for JSON  (and/or JAXB annotations via JAXB
module).

While JAXB is more powerful for producing XML (in areas of XML Schema
support and exotic XML features), Jackson XML module has more powerful
data binding features, same as standard JSON part has. So it may be
worth investigating.

-+ Tatu +-

--
You received this message because you are subscribed to the Google Groups "dropwizard-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-us...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Paul Philion

unread,
Jul 15, 2013, 5:59:59 PM7/15/13
to dropwiz...@googlegroups.com
That's good info, thanks...

I would prefer to use Jackson XML (using jackson-dataformat-xml, I assume) and a custom serializer. But every search I do for jackson custom XML serializer turns up JSON examples, mostly at the scalar level. I haven't yet found an example for root objects in XML.

Do you have any links handy, or just what class I should be extending/implementing (which I'm pretty sure I can figure out how to register with the mapper in DW)?

Thanks!

Tatu Saloranta

unread,
Jul 15, 2013, 6:17:07 PM7/15/13
to dropwiz...@googlegroups.com
On Mon, Jul 15, 2013 at 2:59 PM, Paul Philion <phi...@gmail.com> wrote:
That's good info, thanks...

I would prefer to use Jackson XML (using jackson-dataformat-xml, I assume) and a custom serializer. But every search I do for jackson custom XML serializer turns up JSON examples, mostly at the scalar level. I haven't yet found an example for root objects in XML.


I think this is partly because ideally things would actually work "just the same", minus some additional annotations for dealing with things like namespaces.
So the difference would just be that you create `XmlMapper` instead of plain `ObjectMapper`; and it would Just Work.

If you need to write custom serializers, deserializers, in theory that too works via Streaming API; and translation to/from XML structures are handled at lower level by XML-specific subtypes of `JsonParser` and `JsonGenerator`. But there are some gotchas there.

If you have specific cases, perhaps we could discuss those on Jackson lists?

 
Do you have any links handy, or just what class I should be extending/implementing (which I'm pretty sure I can figure out how to register with the mapper in DW)?


It really should be as simple as including jackson-jaxrs-xml-provider in classpath, as Jersey (and JAX-RS in general) supports pluggability of MessageBodyReaders and MessageBodyWriters (main abstractions for different media types).
Default handlers Jersey has will have lower precedence.

Alternative way in JAX-RS world would be to hook these during bootstrapping, either by instantiating JAX-RS provider class, or passing class as Singleton.
But DropWizard may have other means of injecting MBR/MBW instances?

Has anyone used Jackson XML module with DropWizard? It'd be great to have samples from users.

-+ Tatu +-

Paul Philion

unread,
Jul 16, 2013, 12:44:23 PM7/16/13
to dropwiz...@googlegroups.com
Greetings!

Using XmlMapper does everything I want it to, as you describe below.

I have jackson-jaxrs-xml-provider:2.1.4 in my classpath (versioned to match the other Jackson dependencies in DW 1.6.2).

As far I as I can tell, DW is still using the old JAXB stuff. I am not getting the same output via the Resource request as I am from the XML mapper directly.

Is there something special I can do to confirm that I'm using JAXB vs Jackson?

- Paul

Tatu Saloranta

unread,
Jul 16, 2013, 2:02:55 PM7/16/13
to dropwiz...@googlegroups.com
On Tue, Jul 16, 2013 at 9:44 AM, Paul Philion <phi...@gmail.com> wrote:
Greetings!

Using XmlMapper does everything I want it to, as you describe below.


Ok good. I hope my initial disclaimer (that Maps, Collections are often problematic with XML) didn't scare you or others too much. It was more a warning that sometimes thing get trickier. :-)

 
I have jackson-jaxrs-xml-provider:2.1.4 in my classpath (versioned to match the other Jackson dependencies in DW 1.6.2).

As far I as I can tell, DW is still using the old JAXB stuff. I am not getting the same output via the Resource request as I am from the XML mapper directly.

Is there something special I can do to confirm that I'm using JAXB vs Jackson?


I did not think so. But I think JAX-RS must have some way to override MBR/MBW to use via system properties, since it uses Service Provider Interface metadata:

javax.ws.rs.ext.MessageBodyReader
javax.ws.rs.ext.MessageBodyWriter

where you can specify implementation classes.

It is however possible that DropWizard might be explicitly specifying some providers.
I don't remember how this works from DropWizard sources, but core module should have logic for this.

-+ Tatu +-

philion

unread,
Jul 16, 2013, 7:50:05 PM7/16/13
to dropwiz...@googlegroups.com
Tatu,

Thank you! That's exactly what I needed: MessageBodyWriter. I wrote an implementation that used XmlMapper under the covers and it seems to work!

Also important: Register the provider with Dropwizard, including ResourceTest (which I use a lot). I think the reason I was getting so confused is because I did not register the MessageBodyWriter as a provider for ResourceTest.

Now, I'm have one last question (with a specific example): Why isn't @XmlRootElement setting the root element name properly?

Sample code:

import java.util.HashMap;
import javax.xml.bind.annotation.XmlRootElement;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class XmlTest {
    @XmlRootElement(name="AppConfig")
    public static class MyMap extends HashMap<String,Object> {
        public Object getValue() {
            return this.get("value");
        }
        public void setValue(Object value) {
            this.put("value", value);
        }
    }
    
    public static void main(String[] args) throws Exception {
        XmlMapper xmapper = new XmlMapper();
        
        MyMap root2 = new MyMap();
        root2.setValue("value4");
        root2.put("otherKey", "otherValue");
        
        MyMap part3 = new MyMap();
        part3.setValue("value5");
        part3.put("otherKey", "otherValue");
        root2.put("part3", part3);
        
        MyMap part4 = new MyMap();
        part4.setValue("value6");
        part4.put("otherKey", "otherValue");
        root2.put("part4", part4);
        
        System.out.println(xmapper.writeValueAsString(root2));
    }
}

This produces:

<MyMap xmlns="">....</MyMap>

Also, is there a way to turn off the empty namespace?

Tatu Saloranta

unread,
Jul 16, 2013, 11:09:16 PM7/16/13
to dropwiz...@googlegroups.com
On Tue, Jul 16, 2013 at 4:50 PM, philion <phi...@gmail.com> wrote:
Tatu,

Thank you! That's exactly what I needed: MessageBodyWriter. I wrote an implementation that used XmlMapper under the covers and it seems to work!


Right, this is what the XML provider from:

https://github.com/FasterXML/jackson-jaxrs-providers

does -- project produces 3 different providers; one for json (jackson-jaxrs-json-provider), xml (jackson-jaxrs-xml-provider) and smile (jackson-jaxrs-smile-provider).

Although writing one by hand is not very hard either, and is sometimes good for adding custom config etc.

 
Also important: Register the provider with Dropwizard, including ResourceTest (which I use a lot). I think the reason I was getting so confused is because I did not register the MessageBodyWriter as a provider for ResourceTest.


Ok.
 
Now, I'm have one last question (with a specific example): Why isn't @XmlRootElement setting the root element name properly?


You still need to register JAXB annotation introspector; by default only JacksonAnnotationIntrospector is used. So same way as with JSON provider.
Maybe this is missing? It should work otherwise.

-+ Tatu +-
 

Yun Zhi Lin

unread,
Feb 17, 2014, 5:56:13 AM2/17/14
to dropwiz...@googlegroups.com
The information provided by Tatu on this thread has been very useful when I was searching for the answer on how to use Dropwizard with XMLs. I wanted to contribute by sharing a DW specific XML provider I wrote that extends jackson-jaxrs-xml-provider and jackson-dataformat-xml. It mimics the behaviour of the the vanilla JacksonMessageBodyProvider by:
  • adding support for Validator in the JacksonXMLProvider
  • registering necessary modules such as Logback and JodaTime in the XmlMapper
  • uses woodstox under the hood as recommended by jackson-dataform-xml
It's built with gradle with all dependencies taken care of and should plug into a DW application seamlessly. 

The code is available here: https://github.com/yunspace/dropwizard-xml and comes with a sample project. I've been using this provider at work to parse XML-based financial data and it's quite handy. Hopefully this will save some time for DW users who need to support XML and don't want to write everything from scratch. All feedback welcome.

Tatu Saloranta

unread,
Feb 17, 2014, 12:47:12 PM2/17/14
to dropwiz...@googlegroups.com
Excellent! I hope you don't mind my adding a link form Jackson XML module's readme page to this project. It sounds like great addition.

Another possibly interesting addition would be CSV module; and I think it makes sense to add convenience extension to properly configure these for use with DW, given that there are additional standard types that need to be supported.

-+ Tatu +-



--

Yun Zhi Lin

unread,
Feb 17, 2014, 5:45:24 PM2/17/14
to dropwiz...@googlegroups.com


On Tuesday, February 18, 2014 4:47:12 AM UTC+11, Tatu Saloranta wrote:
Excellent! I hope you don't mind my adding a link form Jackson XML module's readme page to this project. It sounds like great addition.

Thanks Tatu, sure thing. 
 
Another possibly interesting addition would be CSV module; and I think it makes sense to add convenience extension to properly configure these for use with DW, given that there are additional standard types that need to be supported.

-+ Tatu +-

I guess the next question would be should such extensions be merged into DW or kept separate in order to maintain DW's purpose of being a lightweight JSON based web services.
Reply all
Reply to author
Forward
0 new messages