2012-05-22 40 views
1

我有一些jaxb对象建模与具有值的容器对象,可能是另一个容器对象或只是一个简单的对象(例如字符串)的元数据结构。泽西杰克逊重复JSON容器属性

@XmlRootElement(name = "value") 
public class Value 
{ 

    protected SimpleType type; 
    protected Container container; 

    @XmlElement 
    public SimpleType getType() 
    { 
     return type; 
    } 

    public void setType(SimpleType type) 
    { 
     this.type = type; 
    } 

    @XmlInverseReference(mappedBy="value") 
    @XmlElement 
    public Container getContainer() 
    { 
     return container; 
    } 

    public void setContainer(Container container) 
    { 
     this.container = container; 
    } 
} 

@XmlRootElement(name = "container") 
public class Container 
{ 
    protected Value value; 

    @XmlElement 
    public Value getValue() 
    { 
     return value; 
    } 

    public void setValue(Value value) 
    { 
     this.value = value; 
    } 
} 

@XmlRootElement(name = "type") 
@XmlEnum 
public enum SimpleType 
{ 
     @XmlEnumValue("String")STRING, 
     @XmlEnumValue("Boolean")BOOLEAN, 
....etc. 
} 

XML显示正常,但JSON最终具有重复的“容器”属性。

 <container> 
      <value> 
      <container> 
       <value> 
       <type>String</type> 
       </value> 
      </container> 
      </value> 
     </container> 

      "container": { 
       "value": { 
       "container": { 
        "container": { 
        "value": { 
         "type": "STRING" 
        } 
        } 
       } 
       } 
      } 

任何想法为什么这种差异?

回答

0

注:我是EclipseLink JAXB (MOXy)铅和JAXB (JSR-222)专家小组的成员。

由于您的模型中包含MOXy的@XmlInverseReference注释,因此您可能对如何适用于JSON案例感兴趣。

的input.xml

从我可以从你的问题告诉,XML表示应该是下面的,如果你有ContainerValue之间的双向关系:

<?xml version="1.0" encoding="UTF-8"?> 
<container> 
    <value> 
     <type>String</type> 
    </value> 
</container> 

域模型

下面是您的域模型如何映射。我已经指定了@XmlAccessorType(XmlAccessType.FIELD)并删除了访问器方法以缩短示例。

集装箱

package forum10706457; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "container") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Container 
{ 
    protected Value value; 

} 

package forum10706457; 

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlInverseReference; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class Value 
{ 

    protected SimpleType type; 

    @XmlInverseReference(mappedBy="value") 
    protected Container container; 

} 

SimpleType的

package forum10706457; 

import javax.xml.bind.annotation.*; 

@XmlEnum 
public enum SimpleType 
{ 
     @XmlEnumValue("String")STRING, 
     @XmlEnumValue("Boolean")BOOLEAN, 
} 

jaxb.properties

@XmlInverseReference注解是一个莫西扩展,所以你需要在同一个包添加名为jaxb.properties文件与以下条目域模型指定莫西作为JAXB供应商。下面

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

演示

代码演示了如何加载XML文档,然后将所得的物体编组到JSON。检查完成以查看是否填充了双向关系。

package forum10706457; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Container.class); 

     File xml = new File("src/forum10706457/input.xml"); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Container container = (Container) unmarshaller.unmarshal(xml); 

     System.out.println(container == container.value.container); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty("eclipselink.media-type", "application/json"); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(container, System.out); 
    } 

} 

输出

下面是从运行演示代码的输出。请注意0​​在JSON表示中如何被利用。

true 
{ 
    "container" : { 
     "value" : { 
     "type" : "String" 
     } 
    } 
} 

更多信息