【问题标题】:How to fix "Conflicting getter definitions for property" error in FasterXml Jackson? [duplicate]如何修复 FasterXml Jackson 中的“属性的 getter 定义冲突”错误? [复制]
【发布时间】:2019-06-23 10:14:06
【问题描述】:

我想将下面的 xml 字符串反序列化为 Java 对象,但出现错误 java.lang.IllegalArgumentException: Conflicting getter definitions for property "service"

这是用于反序列化的 XML 字符串:

<result>
<service>service_id</service>
<date>2019-01-30 12:10:33</date>
<status>0</status>
<service>
  <id>123</id>
  <name>name</name>
  <type>90</type>
</service>
</result>

这是 POJO 对象:

@Data
@JacksonXmlRootElement(localName = "result")
public class CustomResult {

   @JacksonXmlProperty(localName = "service")
   private String service;

   @JacksonXmlProperty(localName = "date")
   private String date;

   @JacksonXmlProperty(localName = "status")
   private Integer status;

   @JacksonXmlProperty(localName = "service")
   private Service statusObj;

}

@Data
public class Service {

   @JacksonXmlProperty(localName = "id")
   private Integer id;

   @JacksonXmlProperty(localName = "name")
   private String name;

   @JacksonXmlProperty(localName = "type")
   private Integer type;
}

和我的转换器代码:

try {
       CustomResult result = new XmlMapper().readValue(xmlString, CustomResult.class);
    } catch (IOException e) {
       e.printStackTrace();
    }

我认为出现这个错误是因为同名是两个参数。我使用其余请求从服务器获取此 xml,并且无法更改参数名称。如何修复此错误?

【问题讨论】:

  • S您不能在 XML 中有两个名称相同的标签。重命名其中之一,例如:&lt;serviceid&gt;service_id&lt;/serviceid&gt;
  • 我无权访问服务器。服务器开发人员不想修复 xml
  • 这个链接的第二种回复方法帮助了我:stackoverflow.com/questions/37812973/…

标签: java jackson fasterxml


【解决方案1】:

首先,您的 xml 是有效的。

因为我对 jackson 不太熟悉,所以我的第一次尝试是使用 MOXy 读取文件。这就像 scharm 一样工作,没有任何麻烦。

@Test
public void xml() throws JAXBException, IOException {
    String xml = "<result>\n" +
            "<service>service_id</service>\n" +
            "<date>2019-01-30 12:10:33</date>\n" +
            "<status>0</status>\n" +
            "<service>\n" +
            "  <id>123</id>\n" +
            "  <name>name</name>\n" +
            "  <type>90</type>\n" +
            "</service>\n" +
            "</result>";

    try (ByteArrayInputStream baoust = new ByteArrayInputStream(xml.getBytes())) {
        CustomResult result = unmarshal(baoust, CustomResult.class);
        System.out.println(result);
    }
}

public <T> T unmarshal(final InputStream in, Class<T> clazz) throws JAXBException {
    final Unmarshaller m = createUnmarshaller(clazz);
    return m.unmarshal(new StreamSource(in), clazz).getValue();
}

private <T> Unmarshaller createUnmarshaller(Class<T> clazz) throws JAXBException, PropertyException {
    final JAXBContext context = JAXBContext.newInstance(clazz);
    if (! (context instanceof org.eclipse.persistence.jaxb.JAXBContext)) {
        throw new MissingResourceException("Missing MOXy implementation.",
                "org.eclipse.persistence.jaxb.JAXBContext", "");
    }
    final Unmarshaller m = context.createUnmarshaller();
    m.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_XML);
    m.setProperty(UnmarshallerProperties.BEAN_VALIDATION_MODE, BeanValidationMode.NONE);
    return m;
}

@XmlRootElement(name = "result")
public static class CustomResult {

    public CustomResult() {}

   @XmlElement(name = "service")
   private String service;

   @XmlElement(name = "date")
   private String date;

   @XmlElement(name = "status")
   private Integer status;

   @XmlElement(name = "service")
   private Service statusObj;

}

@XmlType
public static class Service {

    public Service() {}

    @XmlElement(name = "id")
   private Integer id;

    @XmlElement(name = "name")
   private String name;

    @XmlElement(name = "type")
   private Integer type;
}

在这项工作成功之后,我相信杰克逊也能做到这一点。

@Test
public void xml() throws JAXBException, IOException {
    String xml = "<result>\n" +
            "<service>service_id</service>\n" +
            "<date>2019-01-30 12:10:33</date>\n" +
            "<status>0</status>\n" +
            "<service>\n" +
            "  <id>123</id>\n" +
            "  <name>name</name>\n" +
            "  <type>90</type>\n" +
            "</service>\n" +
            "</result>";

    CustomResult result2 = unmarshal(xml, CustomResult.class);
    System.out.println(result2);
}

public <T> T unmarshal(final String input, Class<T> clazz) throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.registerModule(new JaxbAnnotationModule());
    return xmlMapper.readValue(input, clazz);
}

@XmlRootElement(name = "result")
public static class CustomResult {

   public CustomResult() {}

   @JsonIgnore
   private List<Object> service = new ArrayList<>();

   @XmlElement(name = "date")
   private String date;

   @XmlElement(name = "status")
   private Integer status;

   @JsonAnySetter
   public void setServices(String name, Object value) {
       if (value instanceof String) {
           service.add(value);
       }
       if (value instanceof Map) {
           // TODO create new Service object from map entries.
       }
       // error?
   }
}

@XmlType
public static class Service {

    public Service() {}

    @XmlElement(name = "id")
   private Integer id;

    @XmlElement(name = "name")
   private String name;

    @XmlElement(name = "type")
   private Integer type;
}

我希望这对您有所帮助。

【讨论】:

  • 在方法 unmarshal(final String input, Class&lt;T&gt; clazz) 上的行 return xmlMapper.readValue(input, clazz); 抛出异常 java.lang.IllegalArgumentException: Conflicting getter definitions for property "service"...
  • @avazbek 你用的是什么版本的jackson?我用的是 2.9.7。我只是从上面复制代码并且测试运行无异常。
  • 我用的是jackson 2.9.6版
  • 这个链接的第二种回复方法帮助了我:stackoverflow.com/questions/37812973/…
猜你喜欢
  • 2014-04-25
  • 2021-10-04
  • 2015-07-19
  • 1970-01-01
  • 2021-08-24
  • 2019-06-21
  • 2020-01-23
  • 1970-01-01
  • 2018-09-16
相关资源
最近更新 更多