JsonMappingException : [단순 유형, 클래스] 유형에 적합한 생성자가 없습니다. JSON 객체에서 인스턴스를 생성 할 수 없습니다. {

JSON 요청을 가져 와서 처리하려고 할 때 다음 오류가 발생합니다.

org.codehaus.jackson.map.JsonMappingException : [단순 유형, 클래스 com.myweb.ApplesDO] 유형에 적합한 생성자를 찾을 수 없음 : JSON 객체에서 인스턴스를 생성 할 수 없습니다 (유형 정보를 추가 / 활성화해야합니까?).

보내려는 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를 사용하고 있습니다.

편집 : 위의 샘플 클래스 에서이 문제를 일으키는 주요 버그가 포함되었습니다-해결책에 대한 대답을 찾으십시오.



답변

그래서 마침내 문제가 무엇인지 깨달았습니다. 내가 의심 한 것처럼 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() {
    }

}


답변

이것은 다음과 같은 이유로 발생합니다.

  1. 내부 클래스는 정적 으로 정의되어야합니다

    private static class Condition {  //jackson specific    
    }
  2. 클래스에 기본 생성자가없는 것일 수도 있습니다 ( 업데이트 : 그렇지 않은 것 같습니다)

    private static class Condition {
        private Long id;
    
        public Condition() {
        }
    
        // Setters and Getters
    }
  3. 세터가 올바르게 정의되지 않았거나 표시되지 않을 수 있습니다 (예 : 개인 세터)


답변

더미 생성자가 필요없는 다른 솔루션을 추가하고 싶습니다. 더미 생성자는 약간 혼란스럽고 혼란 스럽습니다. 안전한 생성자를 제공 할 수 있으며 생성자 인수에 주석을 달아 Jackson이 생성자 매개 변수와 필드 간의 매핑을 결정할 수 있도록합니다.

다음과 같이 작동합니다. 주석 내부의 문자열은 필드 이름과 일치해야합니다.

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) {
        }

}


답변

이 문제에 부딪쳤을 때 내부 클래스를 사용하여 DO 역할을 수행 한 결과였습니다. 내적 계급의 건설은 (묵묵히) 잭슨이 이용할 수 없었던 폐쇄 계급의 실체가 필요했다.

이 경우 내부 클래스를 자체 .java 파일로 이동하면 문제가 해결되었습니다.


답변

일반적 으로이 오류는 기본 생성자를 만들지 않기 때문에 발생하지만 제 경우에는 부모 클래스 내에서 객체 클래스를 사용했기 때문에 문제가 발생했습니다. 이것은 하루 종일 낭비되었습니다.


답변

Thumb Rule : 매핑 클래스로 사용한 각 클래스의 기본 생성자를 추가합니다. 당신이 이것을보고 문제가 발생합니다!
기본 생성자를 추가하면 작동합니다.


답변

이 구조를 테스트 해 주시겠습니까? 내가 올바른 것을 기억하면 다음과 같이 사용할 수 있습니다.

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

둘째, 각 클래스에 기본 생성자를 추가하여 도움이 될 수도 있습니다.