Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当@JacksonXmlProperty.localName与@JacksonXmlRootElement.localName匹配时,无法反序列化展开的列表_Java_Serialization_Jackson_Deserialization - Fatal编程技术网

Java 当@JacksonXmlProperty.localName与@JacksonXmlRootElement.localName匹配时,无法反序列化展开的列表

Java 当@JacksonXmlProperty.localName与@JacksonXmlRootElement.localName匹配时,无法反序列化展开的列表,java,serialization,jackson,deserialization,Java,Serialization,Jackson,Deserialization,好吧,朋友们。。。我很难在这件事上下定决心。我有一个XML文档,表示类型XmlTestXmlTest具有类型为List的属性childrenchildren是一个未包装的XML集合 问题是,当我将XML源反序列化为XmlTest实例时,它会失败: 以下是我正在使用的XML文档: 如果您编写自定义反序列化程序,则可以正常工作 package api.core.jasper; import java.io.IOException; import java.util.List; import or

好吧,朋友们。。。我很难在这件事上下定决心。我有一个XML文档,表示类型
XmlTest
XmlTest
具有类型为
List
的属性
children
children
是一个未包装的XML集合

问题是,当我将XML源反序列化为
XmlTest
实例时,它会失败:

以下是我正在使用的XML文档:


如果您编写自定义反序列化程序,则可以正常工作

package api.core.jasper;

import java.io.IOException;
import java.util.List;

import org.junit.Test;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;

public class UnitTest {

  @Test
  public void test() throws Exception {
    final ObjectMapper mapper = new XmlMapper();

    final XmlTest before =
        new XmlTest("0", Lists.newArrayList(new XmlTest("0.1", null),
            new XmlTest("0.2", Lists.newArrayList(new XmlTest("0.2.1", null)))));
    System.out.println(before);
    final String xml = mapper.writeValueAsString(before);
    System.out.println(xml);
    final XmlTest after = mapper.readValue(xml, XmlTest.class);
    System.out.println(after);
  }

  @JsonDeserialize(using = XmlTestDeserializer.class)
  @JacksonXmlRootElement(localName = "test")
  public static class XmlTest {
    @JacksonXmlProperty(localName = "id", isAttribute = true)
    public String id;

    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "test")
    public List<XmlTest> children;

    public XmlTest(final String id, final List<XmlTest> children) {
      this.id = id;
      this.children = Optional.fromNullable(children).or(Lists.<XmlTest>newArrayList());
    }

    @Override
    public String toString() {
      return Objects.toStringHelper(this)
          .add("id", id)
          .add("children", children)
          .toString();
    }
  }

  public static class XmlTestDeserializer extends StdDeserializer<XmlTest> {

    protected XmlTestDeserializer() {
      super(XmlTest.class);
    }

    @Override
    public XmlTest deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException,
        JsonProcessingException {
      if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
        throw new IOException("Invalid token, expected START_OBJECT");
      }

      String id = null;
      final List<XmlTest> children = Lists.newArrayList();

      while (jp.nextToken() != JsonToken.END_OBJECT) {
        final String key = jp.getCurrentName();
        jp.nextToken();

        if ("id".equals(key)) {
          id = jp.readValueAs(String.class);
        } else if ("test".equals(key)) {
          final XmlTest child = jp.readValueAs(XmlTest.class);
          if (child != null) {
            children.add(child);
          }
        }
      }

      jp.close();

      return new XmlTest(id, children);
    }
  }
}
包api.core.jasper;
导入java.io.IOException;
导入java.util.List;
导入org.junit.Test;
导入com.fasterxml.jackson.core.JsonParser;
导入com.fasterxml.jackson.core.JsonProcessingException;
导入com.fasterxml.jackson.core.JsonToken;
导入com.fasterxml.jackson.databind.DeserializationContext;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.annotation.JsonDeserialize;
导入com.fasterxml.jackson.databind.desr.std.StdDeserializer;
导入com.fasterxml.jackson.dataformat.xml.XmlMapper;
导入com.fasterxml.jackson.dataformat.xml.annotation.jacksonxmlementwrapper;
导入com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
导入com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
导入com.google.common.base.Objects;
导入com.google.common.base.Optional;
导入com.google.common.collect.list;
公共类单元测试{
@试验
public void test()引发异常{
final ObjectMapper mapper=new XmlMapper();
前的最终测试=
新的XmlTest(“0”,列出.newArrayList(新的XmlTest(“0.1”,空),
新的XmlTest(“0.2”,Lists.newArrayList(新的XmlTest(“0.2.1”,null‘)’);
系统输出打印项次(之前);
最后一个字符串xml=mapper.writeValueAsString(之前);
System.out.println(xml);
final XmlTest after=mapper.readValue(xml,XmlTest.class);
系统输出打印项次(后);
}
@JsonDeserialize(使用=XmlTestDeserializer.class)
@JacksonXmlRootElement(localName=“test”)
公共静态类XmlTest{
@JacksonXmlProperty(localName=“id”,isAttribute=true)
公共字符串id;
@JacksonXmlElementWrapper(useWrapping=false)
@JacksonXmlProperty(localName=“test”)
公开儿童名单;
公共XmlTest(最终字符串id,最终列表子项){
this.id=id;
this.children=可选.fromNullable(children).或(Lists.newArrayList());
}
@凌驾
公共字符串toString(){
返回Objects.toStringHelper(this)
.add(“id”,id)
.添加(“儿童”,儿童)
.toString();
}
}
公共静态类XmlTestDeserializer扩展StdDeserializer{
受保护的XmlTestDeserializer(){
super(XmlTest.class);
}
@凌驾
公共XmlTest反序列化(最终JsonParser jp,最终反序列化上下文ctxt)引发IOException,
JsonProcessingException{
if(jp.getCurrentToken()!=JsonToken.START\u对象){
抛出新IOException(“无效令牌,应为START_对象”);
}
字符串id=null;
final List children=Lists.newArrayList();
while(jp.nextToken()!=JsonToken.END\u对象){
最终字符串键=jp.getCurrentName();
jp.nextToken();
如果(“id”。等于(键)){
id=jp.readValueAs(String.class);
}否则,如果(“测试”。等于(键)){
最终XmlTest子级=jp.readValueAs(XmlTest.class);
if(child!=null){
添加(child);
}
}
}
jp.close();
返回新的XmlTest(id,children);
}
}
}
测试控制台输出:

XmlTest{id=0, children=[XmlTest{id=0.1, children=[]}, XmlTest{id=0.2, children=[XmlTest{id=0.2.1, children=[]}]}]}
<test id="0"><test id="0.1"/><test id="0.2"><test id="0.2.1"/></test></test>
XmlTest{id=0, children=[XmlTest{id=0.1, children=[]}, XmlTest{id=0.2, children=[XmlTest{id=0.2.1, children=[]}]}]}
XmlTest{id=0,children=[XmlTest{id=0.1,children=[]},XmlTest{id=0.2,children=[XmlTest{id=0.2.1,children=[]}]
XmlTest{id=0,children=[XmlTest{id=0.1,children=[]},XmlTest{id=0.2,children=[XmlTest{id=0.2.1,children=[]}]}

我已尝试使用您的示例代码。看起来像是jackson数据格式xml中的一个bug。@EugeneEvdokimov,我同意我今天提交了这个bug
package api.core.jasper;

import static org.junit.Assert.fail;

import java.util.List;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.google.common.collect.Lists;

public class UnitTest {

  @Test
  public void test() throws Exception {
    final ObjectMapper mapper = new XmlMapper();

    final XmlTest before =
        new XmlTest("0", Lists.newArrayList(new XmlTest("0.1", null),
            new XmlTest("0.2", Lists.newArrayList(new XmlTest("0.2.1", null)))));
    final String xml = mapper.writeValueAsString(before);
    final XmlTest after = mapper.readValue(xml, XmlTest.class);

    fail();
  }

  @JacksonXmlRootElement(localName = "test")
  public static class XmlTest {
    private final String id;
    private final List<XmlTest> children;

    @JsonCreator
    public XmlTest(@JsonProperty("id") final String id, @JsonProperty("tests") final List<XmlTest> children) {
      this.id = id;
      this.children = children;
    }

    @JsonProperty("id")
    @JacksonXmlProperty(localName = "id", isAttribute = true)
    public String id() {
      return id;
    }

    @JsonProperty("children")
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "test")
    public List<XmlTest> children() {
      return children;
    }
  }

}
<root id="0">
    <test id="0.1">
        <test id="0.1.1" />
    </test>
    <test id="0.2" />
    <test id="0.3">
        <test id="0.3.1" />
    </test>
</root>
package api.core.jasper;

import java.io.IOException;
import java.util.List;

import org.junit.Test;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;

public class UnitTest {

  @Test
  public void test() throws Exception {
    final ObjectMapper mapper = new XmlMapper();

    final XmlTest before =
        new XmlTest("0", Lists.newArrayList(new XmlTest("0.1", null),
            new XmlTest("0.2", Lists.newArrayList(new XmlTest("0.2.1", null)))));
    System.out.println(before);
    final String xml = mapper.writeValueAsString(before);
    System.out.println(xml);
    final XmlTest after = mapper.readValue(xml, XmlTest.class);
    System.out.println(after);
  }

  @JsonDeserialize(using = XmlTestDeserializer.class)
  @JacksonXmlRootElement(localName = "test")
  public static class XmlTest {
    @JacksonXmlProperty(localName = "id", isAttribute = true)
    public String id;

    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "test")
    public List<XmlTest> children;

    public XmlTest(final String id, final List<XmlTest> children) {
      this.id = id;
      this.children = Optional.fromNullable(children).or(Lists.<XmlTest>newArrayList());
    }

    @Override
    public String toString() {
      return Objects.toStringHelper(this)
          .add("id", id)
          .add("children", children)
          .toString();
    }
  }

  public static class XmlTestDeserializer extends StdDeserializer<XmlTest> {

    protected XmlTestDeserializer() {
      super(XmlTest.class);
    }

    @Override
    public XmlTest deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException,
        JsonProcessingException {
      if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
        throw new IOException("Invalid token, expected START_OBJECT");
      }

      String id = null;
      final List<XmlTest> children = Lists.newArrayList();

      while (jp.nextToken() != JsonToken.END_OBJECT) {
        final String key = jp.getCurrentName();
        jp.nextToken();

        if ("id".equals(key)) {
          id = jp.readValueAs(String.class);
        } else if ("test".equals(key)) {
          final XmlTest child = jp.readValueAs(XmlTest.class);
          if (child != null) {
            children.add(child);
          }
        }
      }

      jp.close();

      return new XmlTest(id, children);
    }
  }
}
XmlTest{id=0, children=[XmlTest{id=0.1, children=[]}, XmlTest{id=0.2, children=[XmlTest{id=0.2.1, children=[]}]}]}
<test id="0"><test id="0.1"/><test id="0.2"><test id="0.2.1"/></test></test>
XmlTest{id=0, children=[XmlTest{id=0.1, children=[]}, XmlTest{id=0.2, children=[XmlTest{id=0.2.1, children=[]}]}]}