Parse JSON tree to plain class using Jackson or its alternatives

后端 未结 2 1007
攒了一身酷
攒了一身酷 2021-01-21 00:31

How to parse that JSON:

{
    \"foo\": {
        \"bar\": {
            \"baz\": \"Hello\"
        },
        \"qux\": \"World\"
    }
}

Into t

相关标签:
2条回答
  • 2021-01-21 00:44

    Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

    This use case may not be possible with Jackson, but can be done when MOXy is used as your JSON-binding provider.

    Foo

    You can take advantage of MOXy's path based mapping for this use case.

    import org.eclipse.persistence.oxm.annotations.XmlPath;
    
    public class Foo {
    
        private String baz;
        private String qux;
    
        @XmlPath("foo/bar/baz/text()")
        public String getBaz() {
            return baz;
        }
    
        public void setBaz(final String baz) {
            this.baz = baz;
        }
    
        @XmlPath("foo/qux/text()")
        public String getQux() {
            return qux;
        }
    
        public void setQux(final String qux) {
            this.qux = qux;
        }
    
    }
    

    Demo

    The JAXB runtime APIs are used to read/write the JSON.

    import java.util.*;
    import javax.xml.bind.*;
    import javax.xml.transform.stream.StreamSource;
    import org.eclipse.persistence.jaxb.JAXBContextProperties;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            Map<String, Object> properties = new HashMap<String, Object>(2);
            properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
            properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
            JAXBContext jc = JAXBContext.newInstance(new Class[] {Foo.class}, properties);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            StreamSource json = new StreamSource("src/forum15659950/input.json");
            Foo foo = unmarshaller.unmarshal(json, Foo.class).getValue();
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(foo, System.out);
        }
    
    }
    

    input.json/Output

    {
       "foo" : {
          "bar" : {
             "baz" : "Hello"
          },
          "qux" : "World"
       }
    }
    

    For More Information

    • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
    • http://blog.bdoughan.com/2011/08/json-binding-with-eclipselink-moxy.html
    0 讨论(0)
  • 2021-01-21 00:54

    I have found, that this feature is not implemented in Jackson yet, see issue.

    As a workaround, method below can be added into Foo class:

    @JsonProperty("foo")
    public void setFoo(JsonNode jsonNode) {
        this.qux = jsonNode.get("qux").getTextValue();
        this.baz = jsonNode.get("bar").get("baz").getTextValue();
    }
    
    0 讨论(0)
提交回复
热议问题