Джексон настаивает на картировании неизвестного свойства - PullRequest
0 голосов
/ 19 сентября 2018

Все, я использую Jackson 2.9.5

Я пытаюсь проанализировать вывод XML модуля final-stats Blazemeter Taurus .

Существует XML-элемент «Группа» с дочерними элементами «perc» для процентиля.У Perc есть дочерний элемент «name», который не отображен.Я считаю, что дочерний элемент «name» должен игнорироваться, потому что, если я удаляю @JsonIgnorePropertues(ignoreUnknown=true), Джексон взрывается, потому что он не распознает «name».

Однако при десериализации Group имя не игнорируется.Вместо этого я получаю

com.fasterxml.jackson.databind.exc.MismatchedInputException: Невозможно создать экземпляр com.mycompany.myproject.Percentile (хотя существует по крайней мере один создатель): нет конструктора аргумента строки / метода фабрикидесериализовать из строкового значения ('perc / 90.0') в [Source: (BufferedInputStream);строка: 4, столбец: 20] (через цепочку ссылок: com.mycompany.myproject.Group ["perc"] -> java.util.ArrayList [0])

"perc / 90.0"это значение неотображенного элемента «name».

Еще более странно то, что когда я пытаюсь десериализовать только элемент perc, он работает нормально.

ЭтоXML, который терпит неудачу:

<?xml version='1.0' encoding='UTF-8'?>
<Group label="https://myhost.mycompany.com:8443/login?from=%2F">
  <perc value="0.19300" param="90.0">
    <name>perc/90.0</name>
  </perc>
</Group

Это мой код десериализации:

XmlMapper mapper = new XmlMapper();
mapper.registerModule(new JaxbAnnotationModule());
InputStream in =  Thread.currentThread().getContextClassLoader().getResourceAsStream("taurus/group-small.xml");
Group group = mapper.readValue(in, Group.class);

Этот XML-код работает:

<perc value="0.19300" param="90.0">
  <name>perc/90.0</name>
</perc>

С этим кодом десериализации:

XmlMapper mapper = new XmlMapper();
mapper.registerModule(new JaxbAnnotationModule());
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("taurus/percentile2.xml");
Percentile p = mapper.readValue(in, Percentile.class);

Это мои классы картирования:

package com.mycompany.myproject;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement(name="perc")
public class Percentile {

    @XmlAttribute(name="value")
    private double value;

    @XmlAttribute(name="param")
    private double name;

    public double getValue() {
        return value;
    }

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

    public double getName() {
        return name;
    }

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

package com.mycompany.myproject;

import java.util.List;

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

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement(name="Group")
public class Group {

    @XmlAttribute(name="label")
    private String label;
    @XmlElement(name="perc")
    private List<Percentile> responseTimePercentiles;

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public List<Percentile> getResponseTimePercentiles() {
        return responseTimePercentiles;
    }

    public void setResponseTimePercentiles(List<Percentile> responseTimePercentiles) {
        this.responseTimePercentiles = responseTimePercentiles;
    }
}

Спасибо

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Проблема здесь в том, что класс вашей группы определил список процентилей, которые отображаются в элемент списка xml с именем <perc>.Xml вашей группы не содержит элемента списка xml с именем <perc>, но содержит элементы <perc> непосредственно под корневым xml.

Поскольку @XmlElement(name="perc") применяется к полю списка, а @XmlRootElement(name="perc") равно , также применяется к отдельным элементам xcent процентиля, ваше групповое сопоставление ожидает структуру xml, подобную:

<group>
  <perc/>
      <perc/> 
      <perc/>
      <perc/> 
  <perc/> 
<group>

Фактическая структура XML:

<group>
  <perc/> 
  <perc/>
  <perc/> 
<group>

Чтобы получить эту работу, у вас есть 2 варианта:

  1. Изменить XML, чтобы он былсодержащий элемент списка (например, <percentiles>) и измените аннотацию в поле списка на @XmlElement(name="percentiles").

  2. Примите во внимание тот факт, что у вас нет элемента xml, который обозначаетсписок в отображении.Для этого вам необходимо:

    Добавить следующий метод к вашему групповому мапперу:

    @JsonSetter(value = "perc")
    public void setPercentile(Percentile percetile) {
       this.responseTimePercentiles.add(percetile);
    }
    

    Удалить аннотацию @XmlElement(name="perc") изПоле списка в классе Group.

Чистый эффект этого состоит в том, что отображение не ожидает найти содержащий элемент списка в XML и каждый раз встречает <perc> элемент просто добавляет его в список.

0 голосов
/ 19 сентября 2018

В качестве обходного пути работает альтернативный синтаксис, указывая вещи, которые следует игнорировать, например:

@JsonIgnoreProperties({ "internalId", "secretKey" })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...