Рубрики
Без рубрики

Как решить исключение Jackson InvalidDefinitionException для неизменяемых объектов

В своей практике я столкнулся с проблемой, когда во время работы с Spring framework и у меня появился… С пометкой java, учебное пособие, сегодня я узнал, кодирование.

В своей практике я столкнулся с проблемой, когда, когда я работал с Spring framework и у меня был неизменяемый объект, я получил Исключение InvalidDefinitionException во время тестов веб-уровня. Это связано с тем фактом, что Jackson по умолчанию использует конструктор без аргументов и установщики для десериализации объекта из полезной нагрузки JSON. И, конечно же, эта практика приводит к плохому дизайну программного обеспечения. Итак, если вы тоже хотите решить эту проблему, позвольте мне предложить вам мое решение.

Для начала давайте взглянем на мою модель сущности. Обратите внимание на следующий фрагмент кода ниже:

@Value
@Document(collection = "customers")
public class CustomerModel {
    @Id String customerId;
    String companyName;
    String companyEmail;
    String taxId;
    AddressModel billingAddress;
    AddressModel shippingAddress;

}

Здесь вы можете отметить, что я использую здесь аннотацию @Value для того, чтобы получить:

  • Конструктор всех аргументов
  • Все поля являются закрытыми и окончательными
  • Никаких сеттеров

Использование этого класса сущностей на веб-уровне приложения не приводит к проблемам, и сериализация работает должным образом, когда вы вызываете API, например, с помощью внешнего клиента. Однако, когда я пишу тесты для утверждения веб-уровня, я заканчиваю исключением, потому что, как я уже говорил, Jackson не может десериализовать JSON без конструктора и установщиков без аргументов:

Первое решение, которое я нашел на Stackoverflow заключается в создании файла lombok.config в корне моего проекта со следующими параметрами:

lombok.anyConstructor.addConstructorProperties=true

Хотя это не решило проблему. И если вы все еще читаете этот пост, это означает, что это решение также не подходит для вас. Что я нашел в качестве рабочего подхода, так это создать вручную allargsconstructor и аннотировать его для Jackson, как показано в приведенном ниже фрагменте кода:

@Value
@Document(collection = "customers")
public class CustomerModel {

    @Id String customerId;
    String companyName;
    String companyEmail;
    String taxId;
    AddressModel billingAddress;
    AddressModel shippingAddress;

    @JsonCreator
    public CustomerModel(
            @JsonProperty("customerId") String customerId, 
            @JsonProperty("companyName") String companyName, 
            @JsonProperty("companyEmail") String companyEmail, 
            @JsonProperty("taxId") String taxId, 
            @JsonProperty("billingAddress") AddressModel billingAddress, 
            @JsonProperty("shippingAddress") AddressModel shippingAddress) {
        this.customerId = customerId;
        this.companyName = companyName;
        this.companyEmail = companyEmail;
        this.taxId = taxId;
        this.billingAddress = billingAddress;
        this.shippingAddress = shippingAddress;
    }

}

В принципе, я использую здесь две аннотации:

  • @JsonCreator помечает конструктор, который будет явно использоваться Jackson для десериализации
  • @JsonProperty используется в аргументах конструктора, чтобы помочь Джексону получить доступ к конкретным полям во время выполнения

Этот код отлично работает для меня. Кстати, не забудьте выполнить эти действия и для ваших вложенных объектов, если они у вас есть. И я надеюсь, что это поможет и вам тоже.

Если у вас есть проблемы с пружинным загрузчиком, которые вы не знаете, как преодолеть, не стесняйтесь связаться со мной .

Оригинал: “https://dev.to/iuriimednikov/how-to-solve-jackson-invaliddefinitionexception-on-immutable-objects-11f3”