JsonMappingException: Не найден подходящий конструктор для типа [простой тип, класс ]: не может быть создан из объекта JSON

Я получаю следующую ошибку при попытке получить JSON-запрос и обработать его:

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.myweb.ApplesDO]: can not instantiate from JSON object (необходимо добавить/включить информацию о типе?)

Вот JSON, который я пытаюсь отправить:

{
  "applesDO" : [
    {
      "apple" : "Green Apple"
    },
    {
      "apple" : "Red Apple"
    }
  ]
}

В Controller у меня есть следующая сигнатура метода:

@RequestMapping("showApples.do")
public String getApples(@RequestBody final AllApplesDO applesRequest){
    // Method Code
}

AllApplesDO является оберткой ApplesDO:

public class AllApplesDO {

    private List<ApplesDO> applesDO;

    public List<ApplesDO> getApplesDO() {
        return applesDO;
    }

    public void setApplesDO(List<ApplesDO> applesDO) {
        this.applesDO = applesDO;
    }
}

ApplesDO:

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String appl) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom){
        //constructor Code
    }
}

Я думаю, что Jackson не может преобразовать JSON в Java-объекты для подклассов. Пожалуйста, помогите с параметрами конфигурации для Jackson, чтобы преобразовать JSON в Java-объекты. Я использую Spring Framework.

EDIT: Включил основную ошибку, которая вызывает эту проблему в приведенном выше примере класса - Пожалуйста, посмотрите принятый ответ для решения.

Комментарии к вопросу (2)
Решение

Итак, наконец-то я понял, в чем проблема. Это не проблема конфигурации Jackson, как я сомневался.

На самом деле проблема была в классе ApplesDO:

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String apple) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom) {
        //constructor Code
    }
}

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

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String apple) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom) {
        //constructor Code
    }

    //Introducing the dummy constructor
    public ApplesDO() {
    }

}
Комментарии (13)

Это происходит по следующим причинам:

  1. ваш внутренний класс должен быть определен как статический.

    private static class Condition { //jackson specific
    }
  2. Возможно, в вашем классе нет конструктора по умолчанию (UPDATE: Похоже, это не так).

    private static class Condition {
        private Long id;
    
        public Condition() {
        }
    
        // Setters и Getters
    }
  3. Возможно, ваши сеттеры определены неправильно или не видны (например, private setter).

Комментарии (14)

Я хотел бы добавить еще одно решение для этого, что не требует манекен конструктор. С манекеном конструкторы немного сумбурно и впоследствии сбивает с толку. Мы можем обеспечить безопасный конструктор и аннотирование аргументы конструктора мы позволяем Джексон, чтобы определить соответствие между параметром конструктора и области.

так что следующий будет работать. Примечание строки в аннотации должно совпадать с именем Поля.

import com.fasterxml.jackson.annotation.JsonProperty;
public class ApplesDO {

        private String apple;

        public String getApple() {
            return apple;
        }

        public void setApple(String apple) {
            this.apple = apple;
        }

        public ApplesDO(CustomType custom){
            //constructor Code
        }

        public ApplesDO(@JsonProperty("apple")String apple) {
        }

}
Комментарии (5)

Когда я столкнулся с этой проблемой, это был результат попытки использовать внутренний класс, чтобы служить как сделать. Строительство внутреннего класса (молча) требуется экземпляр класса включения -- что было'т доступны в Джексон.

В этом случае, перемещая внутренний класс для своих .файл Java Исправлена проблема.

Комментарии (1)

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

Комментарии (1)

Правило Буравчика: добавить конструктор по умолчанию для каждого класса, который вы использовали в классе сопоставления. Вы пропустили этот вопрос и возникнуть!<БР> Просто добавить конструктор по умолчанию и он должен работать.

Комментарии (0)

Не могли бы вы протестировать эту структуру. Если я правильно помню, вы можете использовать ее таким образом:

{
    "applesRequest": {
        "applesDO": [
            {
                "apple": "Green Apple"
            },
            {
                "apple": "Red Apple"
            }
        ]
    }
}

Во-вторых, пожалуйста, добавьте конструктор по умолчанию в каждый класс, это также может помочь.

Комментарии (4)

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

Заметьте, мои сотрудники.поле имя отображается, чтобы "ANOTHER_NAME" в виде JSON строки.

     String jsonInString="{\"ANOTHER_NAME\":\"John\",\"age\":\"17\"}";
     ObjectMapper mapper = new ObjectMapper();
     Staff obj = mapper.readValue(jsonInString, Staff.class);
     // print to screen

     public static class Staff {
       public String name;
       public Integer age;
       public Staff() {         
       }        

       //@JsonCreator - don't need this
       public Staff(@JsonProperty("ANOTHER_NAME") String   n,@JsonProperty("age") Integer a) {
        name=n;age=a;
       }        
    }
Комментарии (0)

Вы должны создать фиктивный пустой конструктор в нашей модели класса.Так что пока отображение JSON, это установленный сеттера.

Комментарии (0)

Вы должны понимать, какие варианты Джексон доступна для десериализации. В Java, метод имена аргументов не присутствует в скомпилированный код. Что's, почему Джексон может'т, как правило, используют конструкторы для создания вполне определенного объекта со всем уже установленным.

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

Если вы хотите использовать конструктор с Джексоном, вы должны использовать аннотации, как упомянул @PiersyP в его ответ. Вы также можете использовать шаблон строитель. Если вы столкнулись с некоторыми исключениями, удачи. Обработка ошибок в Джексон сосет большое время, это's жесткий, чтобы понять, что бред в сообщениях об ошибках.

Комментарии (2)

Что касается последней публикации у меня была такая же проблема, когда через Ломбок 1.18.* создается проблема.

Мое решение было добавить @NoArgsConstructor (конструктор без параметров), так как @данных включает в себя по умолчанию @RequiredArgsConstructor (конструктор с параметрами).

Ломбок документации https://projectlombok.org/features/all

Что бы решить проблему:

package example.counter;

import javax.validation.constraints.NotNull;

import lombok.Data;

@Data
@NoArgsConstructor
public class CounterRequest {
    @NotNull
    private final Integer int1;

    @NotNull
    private final Integer int2;
}
Комментарии (0)

Для меня этот раньше работал, но обновление библиотек вызвала эта тема появится. Проблема была класса, как это:

package example.counter;

import javax.validation.constraints.NotNull;

import lombok.Data;

@Data
public class CounterRequest {
    @NotNull
    private final Integer int1;

    @NotNull
    private final Integer int2;
}

Используя Ломбок:


    org.projectlombok
    lombok
    1.18.0

Возвращаясь к


    org.projectlombok
    lombok
    1.16.10

Исправили проблему. Не знаю, почему, но хотел задокументировать для будущего.

Комментарии (0)

Не Джексон пользовательские сериализаторы/Десериализаторы также может быть проблема. Хотя он's не ваш случай, это's стоит отметить.

Я столкнулся с тем же исключением, что и произошло.

Комментарии (0)