programing

Json Mapping Exception:형식 [simple type, class]에 적합한 생성자를 찾을 수 없습니다. JSON 개체에서 인스턴스화할 수 없습니다.

shortcode 2022. 7. 19. 22:07
반응형

Json Mapping Exception:형식 [simple type, class]에 적합한 생성자를 찾을 수 없습니다. JSON 개체에서 인스턴스화할 수 없습니다.

JSON 요청을 받아 처리하려고 하면 다음과 같은 오류가 발생합니다.

org.codehouse.map 입니다.Json Mapping Exception:유형 [simple type, class com.myweb]에 적합한 생성자를 찾을 수 없습니다.ApplesDO]: JSON 개체에서 인스턴스화할 수 없습니다(유형 정보 추가/활성화 필요).

보내려고 하는 JSON은 다음과 같습니다.

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

컨트롤러에는 다음 메서드 시그니처가 있습니다.

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

모든 어플리케이션DO는 Apple의 포장지입니다.작업:

public class AllApplesDO {

    private List<ApplesDO> applesDO;

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

    public void setApplesDO(List<ApplesDO> applesDO) {
        this.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 Objects로 변환하기 위한 구성 매개변수에 대해 도와주세요.Spring Framework를 사용하고 있습니다.

편집: 위의 샘플클래스에 이 문제의 원인이 되고 있는 주요 버그를 기재했습니다.해결방법은 승인된 답변을 참조해 주세요.

그래서 나는 마침내 무엇이 문제인지 깨달았다.그것은 내가 의심했던 잭슨 설정 문제가 아니다.

사실 문제는 사과에 있었다.DO 클래스:

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. 클래스에 기본 생성자가 없을 수 있습니다(UPDATE: 그렇지 않은 것 같습니다).

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

더미 컨스트럭터가 필요 없는 다른 솔루션을 추가하고 싶습니다.왜냐하면 더미 컨스트럭터는 조금 지저분하고 혼란스럽기 때문입니다.안전한 컨스트럭터를 제공할 수 있으며 컨스트럭터 인수에 주석을 달아 잭슨이 컨스트럭터 파라미터와 필드 사이의 매핑을 결정할 수 있도록 합니다.

이하도 유효합니다.주석 내부의 문자열은 필드 이름과 일치해야 합니다.

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"
            }
        ]
    }
}

다음으로 도움이 될 수 있는 각 클래스에 기본 생성자를 추가하십시오.

모델 클래스에 더미 빈 생성자를 생성해야 합니다.그래서 json을 매핑할 때 setter 방식으로 설정합니다.

지난번 출판물에 대해서도 Lombok 1.18.*을 사용했을 때와 같은 문제가 발생하였습니다.

@Data에는 기본적으로 @RequiredArgsConstructor(파라미터가 없는 컨스트럭터)가 포함되어 있기 때문에 이 솔루션은 @NoArgsConstructor(파라미터가 있는 컨스트럭터)를 추가하는 것이었습니다.

롬복 매뉴얼 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;
}

생성자에 주석을 달기 시작하면 모든 필드에 주석을 달아야 합니다.

Staff.name 필드는 JSON 문자열의 "ANTHER_NAME"에 매핑되어 있습니다.

     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;
       }        
    }

잭슨이 역직렬화에 사용할 수 있는 옵션이 무엇인지 알아야 합니다.Java에서는 메서드 인수 이름이 컴파일된 코드에 없습니다.그렇기 때문에 잭슨은 일반적으로 컨스트럭터를 사용하여 모든 것이 이미 설정된 잘 정의된 객체를 만들 수 없습니다.

따라서 빈 생성자가 있고 세터도 있는 경우 빈 생성자와 세터를 사용합니다.설정자가 없는 경우는, 몇개의 다크 매직(반사)이 사용됩니다.

Jackson과 컨스트럭터를 함께 사용하려면 그의 답변에서 @PiersyP가 언급한 주석을 사용해야 합니다.빌더 패턴을 사용할 수도 있습니다.만약 당신이 몇 가지 예외를 만난다면 행운을 빌어요.잭슨에서의 에러 처리는 매우 귀찮아, 에러 메세지에서 횡설수설하는 것은 이해하기 어렵다.

모든 엔티티 클래스에 기본 생성자 추가

커스텀 잭슨의 시리얼라이저/디시리얼라이저가 실패하는 것도 문제가 될 수 있습니다.당신의 경우는 아니지만 언급할 가치가 있습니다.

나도 같은 예외에 직면했고 그것이 사실이었다.

예전에는 이 기능이 작동했지만 라이브러리를 업그레이드하면 이 문제가 발생하였습니다.문제는 다음과 같은 수업을 듣는 것이었습니다.

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;
}

롬복 사용:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.0</version>
</dependency>

로의 폴백

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.10</version>
</dependency>

문제를 해결했다.이유는 모르겠지만, 미래를 위해 문서화하고 싶었어요.

언급URL : https://stackoverflow.com/questions/7625783/jsonmappingexception-no-suitable-constructor-found-for-type-simple-type-class

반응형