Не может десериализоваться из значения объекта (без создателя на основе делегатов или свойств) даже при наличии конструктора по умолчанию

У меня есть класс, который выглядит как

class MyClass {
    private byte[] payload;

    public MyClass(){}

    @JsonCreator
    public MyClass(@JsonProperty("payload") final byte[] payload) {
        this.payload = payload;
    }

    public byte[] getPayload() {
        return this.payload;
    }

}

Я использую Джексон для сериализации, а затем для десериализации. Сериализация работает нормально, но во время десериализации я получаю это сообщение об ошибке -

Cannot construct instance of `mypackage.MyClass` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

Я читал об этой проблеме в Интернете и наткнулся на несколько текстов, рекомендующих использовать конструктор по умолчанию или конструктор с аннотацией @JsonCreator. Я попытался добавить оба, но все еще получал это исключение. Что мне здесь не хватает?

Я тестировал нравится с Jackson 2.9.7, и десериализация также прошла нормально.

haba713 08.10.2018 22:55
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
26
1
49 528
7

Ответы 7

Обновлено:

Я только что нашел гораздо лучшее решение, добавьте ПаранамерМодуль к ObjectMapper:

mapper.registerModule(new ParanamerModule());

Maven:

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-paranamer</artifactId>
    <version>${jackson.version}</version>
</dependency>

Преимущество перед ParameterNamesModule, по-видимому, состоит в том, что классы не нужно компилировать с аргументом -parameters.

КОНЕЦ РЕДАКТИРОВАНИЯ


В Jackson 2.9.9 я попытался десериализовать этот простой POJO и получил то же исключение, добавив конструктор по умолчанию, решивший проблему:

POJO:

public class Operator {

    private String operator;

    public Operator(String operator) {
        this.operator = operator;
    }

    public String getOperator() {
        return operator;
    }
}

ObjectMapper и Serialize / Deserialize:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.setVisibility(PropertyAccessor.CREATOR, Visibility.ANY);

String value = mapper.writeValueAsString(new Operator("test"));
Operator result = mapper.readValue(value, Operator.class);

JSON:

{"operator":"test"}

Исключение:

com.fasterxml.jackson.databind.exc.MismatchedInputException: 
Cannot construct instance of `...Operator` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"operator":"test"}"; line: 1, column: 2]

Решение (POJO с конструктором по умолчанию):

public class Operator {

    private String operator;

    private Operator() {
    }

    public Operator(String operator) {
        this();
        this.operator = operator;
    }

    public String getOperator() {
        return operator;
    }
}

Добавление модуля paranamer не решает проблему того, что Джексон не может создать объект из-за отсутствия пустого конструктора. Протестировано с параметром 2.12.2

carlos palma 16.04.2021 18:13

ваше решение запрещает окончательные свойства из-за Джексона. urg.

mmm 19.07.2021 19:25

Я заметил ту же проблему. Моя проблема была вызвана тем, что я использовал тип неправильный JsonCreator. Я неправильно использовал org.codehaus.jackson.annotate.JsonCreator, но вместо этого мне следовало использовать com.fasterxml.jackson.annotation.JsonCreator.

В объекте вашего подкласса добавьте конструктор по умолчанию:

public NameOfClass() {
    super();
}
@Data (который добавляет @RequiredArgsConstructor) действительно было недостаточно. Мне пришлось сделать свойство не-final и добавить @NoArgsConstructor
lilalinux 03.06.2021 16:38

Я наткнулся на сериализацию и десериализацию kotlin data classes. Все, что мне нужно было сделать, это добавить значения по умолчанию для моих свойств, а затем прочитать значения.

data class DataClass(
  val key: String = "",    //  adding these default 
  val value: String = ""   //  values worked
)

без = "" я бы получил ошибку:

Cannot construct instance of `com.xxx.DataClass` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

Я столкнулся с этой же проблемой, и ни одно из вышеперечисленных решений не помогло. Обнаружив, что отладочные сборки работают нормально, R8 был виноват, потому что он удалял некоторый код, необходимый Джексону в сборках выпуска. Добавление @JsonAutoDetect ко всем зависимостям пользовательских классов устранило ошибку.

@JsonAutoDetect
data class Car(
    val name: String // annotation not needed
    val engine: Engine // annotation needed
)
// @JsonAutoDetect is needed here
data class Engine(
    val name: String
)

Я получил эту ошибку и попробовал https://newbedev.com/no-creators-like-default-construct-exist-cannot-deserialize-from-object-value-no-delegate-or-property-based-creator

В основном добавлено

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)

декораторы, и это сработало для меня.

Я также столкнулся с тем же, в моем случае я был в заявлении для использования REST API в Java ... но после нескольких попыток я обнаружил, что мне нужно добавить конструктор по умолчанию, потому что я уже объявил конструктор с полями. .

public NameofClass() {
        super();
        // TODO Auto-generated constructor stub
    }

В том виде, в каком оно написано, ваш ответ неясен. Пожалуйста, редактировать, чтобы добавить дополнительную информацию, которая поможет другим понять, как это решает заданный вопрос. Вы можете найти дополнительную информацию о том, как писать хорошие ответы в справочном центре.

Community 21.09.2021 13:42

пожалуйста, импровизируйте свои комментарии, предоставив фрагменты кода ясными

Dilip D 21.09.2021 14:25

Другие вопросы по теме