Mapping a dynamic JSON object into Java POJO with Jaxb / Jersey

Question!

I would like to map from JSON-Response into my Java Object using Jaxb/Jersey. I have such Json response:

{
"fuzzy": false,
"hits": [
    { ... }
],
"filters": {
    "category": {
        "selected": false,
        "values": { }
        },
        "id": "category",
        "name": "Kategorie"
    },
    "shop": {
        "selected": false,
        "values": {
            "7817": {
                "count": 2,
                "selected": false,
                "numeric_sort_key": null,
                "id": "7817",
                "name": "AZUGA"
            }
        },
        "id": "shop",
        "name": "Shop"
    },
    "11223": {
        "selected": false,
        "values": { },
        "id": "certificate",
        "name": "Vertrauensgarantie"
    },
    "11334": {
        "selected": false,
        "values": {
            "2290": {
                "count": 1,
                "selected": false,
                "numeric_sort_key": null,
                "id": "2290",
                "name": "22.90"
            }
        },
        "id": "price",
        "name": "Preis"
    }
},
"total_hits": 2

}

And this is the bean I'd like to map the Json-response into:

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



@XmlRootElement
public class RestBean {

    @XmlElement
    private String fuzzy;

    @XmlElement
    private List<HitsBean> hits;

    @XmlElement
    private Filters filters;

    @XmlElement
    private String total_hits;
}

The problem is, the child elements of "filters" are dynamic, that means there is no way to know the name of the child element "11223" and "11334" in advance, since they are created in runtime. Here is my Filters bean:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement(name="filters")
@XmlAccessorType(XmlAccessType.FIELD)
public class Filters {

    @XmlElement
    private Filter category;

    @XmlElement
    private Filter shop;

    @XmlAnyElement
    @XmlMixed
    private List<Filter> filt;
}

But the annotation @XmlAnyElement always throws out such error :

23.04.2013 16:26:11 com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SCHWERWIEGEND: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified. 
at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.checkQName(CoreDocumentImpl.java:2582)
at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.setName(ElementNSImpl.java:117)
at com.sun.org.apache.xerces.internal.dom.ElementNSImpl.<init>(ElementNSImpl.java:80)
at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.createElementNS(CoreDocumentImpl.java:2095)
at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.startElement(SAX2DOM.java:164)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.closeStartTag(ToXMLSAXHandler.java:204)
at com.sun.org.apache.xml.internal.serializer.ToSAXHandler.flushPending(ToSAXHandler.java:277)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.startElement(ToXMLSAXHandler.java:646)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerHandlerImpl.startElement(TransformerHandlerImpl.java:263)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.DomLoader.startElement(DomLoader.java:107)
...

My question is, how should I map a dynamic generated Json-Response, at this case the "11223" and "11334"? Thank you very much in advance.

Regards, Suparno



Answers

It very simple using Jackson mapper and @JsonAnyGetter/@JsonAnySetter (org.codehaus.jackson.annotate package) annotations.
Class Filters (it's important to use here getters/setters and default XmlAccessorType)

public class Filters {

    private Filter category;

    private Filter shop;

    private Map
By : Ilya


This video can help you solving your question :)
By: admin