如何使用EclipseLink MOXy JAXB提供程序解组JSON数组

时间:2015-11-01 20:29:44

标签: jaxb eclipselink unmarshalling moxy

这看起来很简单,但我必须遗漏一些东西。我要做的就是解组一个JSON数组。我有一些代码,当JSON是一个简单的对象时,但是当我把它变成一个数组(即带有[]的带有JSON的JSON)时,它会失败。以下是示例json,域类,解组代码和异常。任何帮助将不胜感激。

示例JSON: [{"CreateIndex":24988,"ModifyIndex":132476,"LockIndex":0,"Key":"Redirector","Flags":0} ]

域:

package eclipselink.example.moxy.json.simple.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Optional;
import com.google.common.io.BaseEncoding;
import com.orbitz.consul.model.kv.ImmutableValue;
import com.orbitz.consul.util.UnsignedLongDeserializer;

@org.immutables.value.Value.Immutable
@JsonDeserialize(as = ImmutableValue.class)
@JsonSerialize(as = ImmutableValue.class)
@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MyValue {

    @XmlAttribute
private long createIndex;
    @XmlAttribute
private long modifyIndex;
    @XmlAttribute
private long lockIndex;
    @XmlAttribute
private String key;
    @XmlElement
private long flags;

    @XmlElement(nillable = true)
private Optional<String> value;
    @XmlElement
private Optional<String> session;


    @JsonProperty("CreateIndex")
    public long getCreateIndex() {
        return createIndex;
    }

    @JsonProperty("ModifyIndex")
    public  long getModifyIndex() {
        return modifyIndex;
    }


    @JsonProperty("LockIndex")
    public  long getLockIndex() {
        return lockIndex;
    }


    @JsonProperty("Key")
    public  String getKey() {
        return key;
    }


    @JsonProperty("Flags")
    @JsonDeserialize(using=UnsignedLongDeserializer.class)
    public long getFlags() {
        return flags;
    }

    @JsonProperty("Value")
    public Optional<String> getValue() {
        return value;
    }

    @JsonProperty("Session")
    public Optional<String> getSession() {
        return session;
    }

    @JsonIgnore
    @org.immutables.value.Value.Lazy
    public Optional<String> getValueAsString() {

        if (getValue() != null && getValue().isPresent()) {
            return Optional.of(
                    new String(BaseEncoding.base64().decode(getValue().get()))
            );
        } else {
            return Optional.absent();
        }

    }
}

Unmarshall代码:

public class Main_JSON_redirector {

    private static final String INPUT_XML = "META-INF/input.xml";
    private static final String INPUT_JSON_URL = "http://192.168.85.186:8500/v1/kv/Redirector"; 
    private static final File INPUT_JSON_FILE = new File("C:/Users/dnance/EclipseLink-examples/moxy/json-simple/src/main/resources/META-INF/redirector.json");

    public static void main(String[] args) throws Exception {
        System.out.println();
        System.out.println("Running EclipseLink MOXy Simple MAIN_JSON Example");

        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {MyValue.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
        unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);

        StreamSource source = new StreamSource(INPUT_JSON_FILE);
        JAXBElement<MyValue[]> jaxbElement = unmarshaller.unmarshal(source, MyValue[].class);
 MyValue[] value = jaxbElement.getValue();
System.out.println("value: " + value[0].getValueAsString());
...

例外:

Running EclipseLink MOXy Simple MAIN_JSON Example
Exception in thread "main" javax.xml.bind.UnmarshalException
 - with linked exception:
[Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class [Leclipselink.example.moxy.json.simple.model.MyValue; was not found in the project.  For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.]
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:1072)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:341)
    at eclipselink.example.moxy.json.simple.Main_JSON_redirector.main(Main_JSON_redirector.java:58)
Caused by: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class [Leclipselink.example.moxy.json.simple.model.MyValue; was not found in the project.  For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
    at org.eclipse.persistence.exceptions.XMLMarshalException.descriptorNotFoundInProject(XMLMarshalException.java:154)
    at org.eclipse.persistence.internal.oxm.Context$ContextState.getSession(Context.java:137)
    at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:798)
    at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:1)
    at org.eclipse.persistence.internal.oxm.Context.getSession(Context.java:458)
    at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:366)
    at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:1)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:837)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:710)
    at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:643)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:339)

1 个答案:

答案 0 :(得分:0)

您只需要在unmarshal方法中指定类型类而不是数组类,例如

Collection<MyValue> myValues = (Collection<MyValue>) unmarshaller.unmarshal(source, MyValue.class).getValue();

因为你有unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);它才有效。没有它解组返回JAXBElement<Collection<JAXBElement>>