JAXBMarshaller和JAXBUnmarshaller彼此不兼容

时间:2014-07-23 12:11:53

标签: java json jaxb jersey moxy

当我尝试使用包含单个元素数组的对象并且JSON_WRAPPER_AS_ARRAY_NAME设置为TRUE时,JAXBMarshaller和JAXBUnmarshaller不兼容。当我使用Jersey 2.9.1并将Moxy设置为JSON提供程序时,我遇到此问题。为了简化这种情况,我已经在调试器中检查了使用了哪些类并创建了一个测试用例:

我正在将一个对象编组为一个字符串,然后将该字符串传递给Unmarshaller。令人惊讶的是,生成的对象与输入对象不同。

豆类:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
  @XmlElementWrapper(name = "children")
  @XmlElement(name = "child")
  private Collection<Child> children;

  public Collection<Child> getChildren() {
    return children;
  }

  public void setChildren(Collection<Child> children) {
    this.children = children;
  }

  @Override
  public String toString() {
    return String.format("Parent [children=%s]", children);
  }
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Child {

  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return String.format("Child [name=%s]", name);
  }
}

测试用例:

import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;
...

@Test
  public void jsonTest() throws JAXBException {

    boolean wrapperAsArrayName = true;
    JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] { Parent.class }, null);
    Parent parent = new Parent();
    parent.setChildren(new ArrayList<Child>());
    Child child1 = new Child();
    child1.setName("Marek");
    parent.getChildren().add(child1);

    Marshaller marshaller = jaxbContext.createMarshaller();
    marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
    marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, wrapperAsArrayName);

    OutputStream baos = new ByteArrayOutputStream();
    marshaller.marshal(parent, baos);

    String marshalled = baos.toString();
    System.out.println(marshalled);

    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON);
    unmarshaller.setProperty(UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, wrapperAsArrayName);

    InputStream bais = new ByteArrayInputStream(marshalled.getBytes(StandardCharsets.UTF_8));
    Parent result = (Parent)unmarshaller.unmarshal(bais);
    System.out.println(result);
    assertEquals(result.getChildren().size(), parent.getChildren().size());
  }

结果: JSON_WRAPPER_AS_ARRAY_NAME = true:

{"parent":{"children":[{"name":"Marek"}]}}
Parent [children=[]]
java.lang.AssertionError

JSON_WRAPPER_AS_ARRAY_NAME = false:

{"parent":{"children":{"child":[{"name":"Marek"}]}}}
Parent [children=[Child [name=Marek]]]

对于包含多个元素的集合没有问题:

{"parent":{"children":[{"name":"Marek"},{"name":"Marek2"}]}}
Parent [children=[Child [name=Marek], Child [name=Marek2]]]

{"parent":{"children":{"child":[{"name":"Marek"},{"name":"Marek2"}]}}}
Parent [children=[Child [name=Marek], Child [name=Marek2]]]

0 个答案:

没有答案