JSON이있는 Jackson : 인식 할 수없는 필드, 무시할 수없는 것으로 표시되지 않음


675

특정 JSON 문자열을 Java 객체로 변환해야합니다. JSON 처리에 Jackson을 사용하고 있습니다. 입력 JSON을 제어 할 수 없습니다 (웹 서비스에서 읽었습니다). 이것은 내 입력 JSON입니다.

{"wrapper":[{"id":"13","name":"Fred"}]}

간단한 사용 사례는 다음과 같습니다.

private void tryReading() {
    String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    ObjectMapper mapper = new ObjectMapper();  
    Wrapper wrapper = null;
    try {
        wrapper = mapper.readValue(jsonStr , Wrapper.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("wrapper = " + wrapper);
}

내 엔티티 클래스는 다음과 같습니다

public Class Student { 
    private String name;
    private String id;
    //getters & setters for name & id here
}

내 래퍼 클래스는 기본적으로 학생들의 목록을 얻는 컨테이너 객체입니다.

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

이 오류가 계속 발생하고 "래퍼"가 반환 null됩니다. 무엇이 빠졌는지 잘 모르겠습니다. 누군가 도와주세요?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

2
:이 래퍼 클래스를 만드는 피하기 위해 유용하다고 Map dummy<String,Student> = myClientResponse.getEntity(new GenericType<Map<String, Student>>(){});다음과Student myStudent = dummy.get("wrapper");
pulkitsinghal

6
JSON은 다음과 같아야합니다. String jsonStr = "{\"students \ "\ : [{\"id \ ": \"13 \ ", \"name \ ": \"Fred \ "}]}"; REST POST 요청에서 래퍼 객체를 예상하는 경우
Dmitri Algazin

2

5
그리고 덧붙여 말하자면, 가장 답변 질문은 실제로 제가 위에서 링케 것과, 즉 하나의 유사한 다른 질문에 대답.
sleske

4
대부분의 답변은 실제로 문제를 해결하기보다는 양탄자 아래에서 문제를 해결하는 데 도움이됩니다. (
NoobEditor

답변:


992

Jackson의 클래스 수준 주석을 사용할 수 있습니다.

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

POJO에 정의하지 않은 모든 속성은 무시합니다. JSON에서 몇 가지 속성을 찾고 전체 매핑을 작성하지 않으려는 경우 매우 유용합니다. Jackson의 웹 사이트 에서 더 많은 정보를 얻을 수 있습니다 . 선언되지 않은 속성을 무시하려면 다음과 같이 작성해야합니다.

@JsonIgnoreProperties(ignoreUnknown = true)

9
아리엘, 클래스 외부에 이것을 선언 할 방법이 있습니까?
Jon Lorusso

4
내가 소유하지 않은 클래스를 직렬화하고 있습니다 (수정 불가). 한 관점에서, 특정 필드 집합으로 직렬화하고 싶습니다. 다른보기에서, 다른 필드 집합을 직렬화하거나 JSON의 속성 이름을 바꾸고 싶습니다.
Jon Lorusso

11
난 당신이 필요합니까 것을 추가해야합니다 (ignoreUnknown = true)그렇지 않으면 주석 클래스 그것을하지 않습니다 일
네크로맨서

85
Julián, 이것은 OP 문제에 대한 정답이 아닙니다. 그러나 사람들은 POJO에 정의되지 않은 속성을 무시하는 방법에 대해 Google이 방문했기 때문에 여기에 온 것으로 의심됩니다. 이는 첫 번째 결과이므로 결과와 Suresh의 응답 (나에게 일어난 일)을 끝내게됩니다. 원래 질문은 정의되지 않은 속성을 무시하고 싶지는 않습니다.
Ric Jafe

5
이것은 매우 어리석은 기본 설정 imho입니다. api에 속성을 추가하면 전체 직렬화가 실패합니다
headsvk

479

당신이 사용할 수있는

ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

선언되지 않은 모든 속성은 무시합니다.


5
이것은 나를 위해 작동하지 않았다, 그것은 여전히 ​​알 수없는 속성에 실패
Denis Kniazhev

1
정확히 내가하고있는 일을 최소한의 코드로 붙여 넣으십시오. 무언가를 놓쳤을 수도 있습니다 ..이 작업을 수행하거나 "@JsonIgnoreProperties (ignoreUnknown = true)"를 사용하여 문제를 해결해야합니다. 어쨌든 행운을 빈다.
Suresh

27
FWIW-이 약간 다른 열거 형을 가져와야했습니다. org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES
raf

9
^ 위의 2
755

10
getObjectMapper (). disable (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
icfantv

126

첫 번째 대답은 거의 정확하지만 필요한 것은 필드가 아닌 getter 메소드를 변경하는 것입니다. 필드는 비공개입니다 (자동 감지되지 않음). 더 나아가, getter는 두 필드가 모두 보이는 경우 필드보다 우선합니다.

따라서 getter는 이름을 지정 getWrapper()하거나 다음과 같이 주석을 달아야합니다.

@JsonProperty("wrapper")

getter 메소드 이름을 선호하는 경우.


어떤 게터를 변경하거나 주석을 달아야합니까?
Frans

@JsonGetter ( "wrapper")로 주석이 달린 것을 의미합니까?
pedram bashiri

@pedrambashiri 아니요, 그렇습니다 @JsonProperty. 하지만 @JsonGetter법적 별칭이며, 그것은 거의 사용되지 @JsonProperty게터, 세터와 필드의 작품; setter와 getter는 서명으로 구별 할 수 있습니다 (하나는 인수를 사용하지 않고 무효를 리턴하고 다른 하나는 인수를 사용함).
StaxMan

이것이 내가 찾던 대답입니다! Jackson이 소스 JSON을 POJO에 매핑하는 데 문제가 있지만 게터에 태그를 지정하여 일치를 보장 할 수 있습니다. 감사!
Andrew Kirna

90

Jackson 2.6.0을 사용하면 다음과 같이 작동했습니다.

private static final ObjectMapper objectMapper = 
    new ObjectMapper()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

그리고 설정 :

@JsonIgnoreProperties(ignoreUnknown = true)

12
구성 주석이 필요하지 않습니다
neworld

클래스에서 ObjectMapper와 Annotation을 모두 구성해야합니까? 나는 objectMapper가 각 클래스에 주석을 달지 않고도 모든 것을 고칠 것이라고 생각합니다. 그래도 주석을 사용합니다.
prayagupd

같은 클래스에 두 설정이 모두 필요하지 않습니다. DI를 사용하여 전역 단일 속성 인스턴스를 가져 와서 속성을 전역으로 ObjectMapper설정할 수도 FAIL_ON_UNKNOWN_PROPERTIES있습니다.
user991710

둘 다 필요하지 않습니다. 둘 중 하나를 선택할 수 있습니다.
heez

58

두 가지 방법으로 달성 할 수 있습니다.

  1. 알려지지 않은 특성을 무시하도록 POJO를 표시하십시오.

    @JsonIgnoreProperties(ignoreUnknown = true)
  2. POJO / json을 직렬화 / 역 직렬화하는 ObjectMapper를 다음과 같이 구성하십시오.

    ObjectMapper mapper =new ObjectMapper();            
    // for Jackson version 1.X        
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // for Jackson version 2.X
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 

2
이것이 왜 대답이되어야합니까? 이것은 알 수없는 속성을 무시하도록 지시하는 반면, 질문은이 솔루션이 분명히 무시한다고 말하는 객체에 json을 감싸는 방법을 찾는 것이 었습니다.
Sayantan

42

이것은 나를 위해 완벽하게 작동했습니다.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
    DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

@JsonIgnoreProperties(ignoreUnknown = true) 주석이 없습니다.


2
OP의 질문에 대답하지 않으므로 하향 투표되었습니다. 알 수없는 속성을 무시해도 문제가 해결되지 않지만 Wrapper학생 목록이 null비어 있거나 빈 인스턴스가 남아 있습니다.
Frans

37

모두보다 낫습니다.이 숙박 시설을 참조하십시오.

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    projectVO = objectMapper.readValue(yourjsonstring, Test.class);

예상대로 작동합니다!
MADHAIYAN M

예, 이것이 내 문제를 해결 한 것입니다-이 게시물의 제목과 일치합니다.
Scott Langeberg

답변은 잘 작동하며 매우 쉽습니다. 감사합니다
Touya Akira

29

Jackson 2.0을 사용하는 경우

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

왜이 구성이 나에게 영향을 미치지 않습니까?
zhaozhi

@zhaozhi 그것은 잭슨의 버전에 따라 달라집니다
Aalkhodiry

20

문서 에 따르면 선택한 필드 또는 모든 알려진 필드를 무시할 수 있습니다.

 // to prevent specified fields from being serialized or deserialized
 // (i.e. not include in JSON output; or being set even if they were included)
 @JsonIgnoreProperties({ "internalId", "secretKey" })

 // To ignore any unknown properties in JSON input without exception:
 @JsonIgnoreProperties(ignoreUnknown=true)

15

다음 코드로 나를 위해 일했습니다.

ObjectMapper mapper =new ObjectMapper();    
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

15

세터와 게터를 추가하면 문제가 해결되었습니다. 실제 문제는 그것을 해결하는 방법이지만 오류를 억제 / 무시하는 방법은 아니라고 생각했습니다. " 인식 할 수없는 필드입니다. 무시할 수없는 것으로 표시되었습니다." "

클래스 위에 아래 주석을 사용했지만 json 객체를 구문 분석하고 입력 할 수 없었습니다.

@JsonIgnoreProperties (ignoreUnknown = true)

그런 다음 세터와 게터를 추가하지 않았다는 것을 깨달았습니다. 세터와 게터를 "래퍼"와 "학생"에 추가 한 후에는 매력처럼 작동했습니다.


이것은 실제로 질문에 대답하는 유일한 대답 인 것 같습니다. 다른 모든 답변은 알 수없는 속성을 무시 된 것으로 표시하지만 '래퍼'는 알 수없는 속성이 아니며 구문 분석하려는 것입니다.
lbenedetto

14

Jackson은 래퍼 클래스에서 "래퍼"라는 필드를 찾을 수 없기 때문에 불평하고 있습니다. JSON 개체에 "래퍼"라는 속성이 있기 때문에이 작업을 수행합니다.

해결 방법은 래퍼 클래스의 필드 이름을 "학생"대신 "래퍼"로 바꾸는 것입니다.


고마워요 나는 그것을 시도했지만 문제를 해결하지 못했습니다. 주석이 없는지 궁금합니다.
jshree

1
흠, Java에서 동등한 데이터를 작성한 다음 Jackson을 사용 하여 JSON으로 데이터를 쓰면 어떻게됩니까 ? 해당 JSON과 위의 JSON 간의 차이점은 무엇이 잘못되었는지에 대한 단서가되어야합니다.
Jim Ferrans

이 답변은 질문의 예와 함께 저에게 효과적이었습니다.
sleske

14

나는 아래의 방법을 시도했고 Jackson과 같은 JSON 형식 읽기에서 작동합니다. 이미 제안 된 솔루션을 사용하여 getter에 주석 달기@JsonProperty("wrapper")

래퍼 클래스

public Class Wrapper{ 
  private List<Student> students;
  //getters & setters here 
} 

래퍼 수업 제안

public Class Wrapper{ 

  private StudentHelper students; 

  //getters & setters here 
  // Annotate getter
  @JsonProperty("wrapper")
  StudentHelper getStudents() {
    return students;
  }  
} 


public class StudentHelper {

  @JsonProperty("Student")
  public List<Student> students; 

  //CTOR, getters and setters
  //NOTE: If students is private annotate getter with the annotation @JsonProperty("Student")
}

그러나 이것은 다음 형식의 출력을 제공합니다.

{"wrapper":{"student":[{"id":13,"name":Fred}]}}

자세한 내용은 https://github.com/FasterXML/jackson-annotations참조하십시오.

도움이 되었기를 바랍니다


stackoverflow에 오신 것을 환영합니다. 팁, {}도구 모음 의 기호를 사용하여 코드 스 니펫을 포맷 할 수 있습니다.
Leigh

11

이 솔루션은 json 스트림을 읽을 때 일반적이며 도메인 클래스에서 올바르게 매핑되지 않은 필드는 무시할 수 있지만 일부 필드 만 가져와야합니다.

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)

자세한 해결책은 jsonschema2pojo와 같은 도구를 사용하여 json Response의 스키마에서 Student와 같은 필수 도메인 클래스를 자동 생성하는 것입니다. 온라인 json에서 스키마 변환기로 후자를 수행 할 수 있습니다.


10

json property와 java property의 이름이 일치하지 않으므로 아래의 필드 학생들에게 주석을 답니다.

public Class Wrapper {
    @JsonProperty("wrapper")
    private List<Student> students;
    //getters & setters here
}

9

아무도 언급하지 않았 듯이, 내가 할 것이라고 생각했습니다 ...

문제는 JSON의 속성을 "래퍼"라고하고 Wrapper.class의 속성을 "학생"이라고합니다.

그래서 ...

  1. 클래스 또는 JSON에서 특성 이름을 정정하십시오.
  2. StaxMan의 설명에 따라 속성 변수에 주석을 답니다.
  3. 세터에 주석 달기 (있는 경우)

6

개인이 아닌 클래스 필드를 공개로 설정 하십시오 .

public Class Student { 
    public String name;
    public String id;
    //getters & setters for name & id here
}

2
나쁜 연습-캡슐화가 깨집니다.
Downhillski

1
들었어
Downhillski

이 필드를 통해 내부 상태가 변경 될 수 있으므로 사용자가 클래스를 사용하면 클래스가 위험에 노출됩니다.
Downhillski

5

나를 위해 일한 것은 재산을 공개하는 것이 었습니다. 그것은 나를 위해 문제를 해결했습니다.


1
나를 위해 일했다 : D
TienLuong

5

변경

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

public Class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}

---- 또는 ----

JSON 문자열을

{"students":[{"id":"13","name":"Fred"}]}

5

입력

{"wrapper":[{"id":"13","name":"Fred"}]}

"wrapper"라는 필드를 가진 개체이며, 이는 Collection of Students입니다. 그래서 나의 추천은

Wrapper = mapper.readValue(jsonStr , Wrapper.class);

어디로 Wrapper정의

class Wrapper {
    List<Student> wrapper;
}

5

새로운 Firebase Android는 큰 변화를 가져 왔습니다. 문서 사본 아래 :

[ https://firebase.google.com/support/guides/firebase-android] :

Java 모델 객체 업데이트

2.x SDK와 마찬가지로 Firebase 데이터베이스는 전달한 Java 객체를 자동 DatabaseReference.setValue()으로 JSON 으로 변환 하고를 사용하여 JSON을 Java 객체로 읽을 수 있습니다 DataSnapshot.getValue().

새로운 SDK에서 JSON을 Java 객체로 읽을 때 DataSnapshot.getValue() 알 수없는 속성이 기본적으로 무시되므로 더 이상 필요하지 않습니다 @JsonIgnoreExtraProperties(ignoreUnknown=true).

Java 객체를 JSON에 쓸 때 필드 / 게터를 제외하기 위해 이제 주석 @Exclude대신에 주석이 호출 됩니다 @JsonIgnore.

BEFORE

@JsonIgnoreExtraProperties(ignoreUnknown=true)
public class ChatMessage {
   public String name;
   public String message;
   @JsonIgnore
   public String ignoreThisField;
}

dataSnapshot.getValue(ChatMessage.class)

AFTER

public class ChatMessage {
   public String name;
   public String message;
   @Exclude
   public String ignoreThisField;
}

dataSnapshot.getValue(ChatMessage.class)

JSON에 Java 클래스에없는 추가 특성이있는 경우 로그 파일에이 경고가 표시됩니다.

W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage

@IgnoreExtraProperties수업에 주석을 달아이 경고를 제거 할 수 있습니다 . Firebase 데이터베이스가 2.x SDK에서와 같이 작동하고 알 수없는 속성이있는 경우 예외를 발생 @ThrowOnExtraProperties시키려면 클래스에 주석을 추가 할 수 있습니다 .


4

내 부분은 유일한 줄

@JsonIgnoreProperties(ignoreUnknown = true)

작동하지 않았다.

그냥 추가

@JsonInclude(Include.NON_EMPTY)

잭슨 2.4.0


4

이것은 나를 위해 완벽하게 작동했습니다.

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

4

POJO 클래스의 setter 및 getter 메소드의 서명을 간단히 변경 하여이 문제를 해결했습니다. 내가해야 할 일은 매퍼가 찾고있는 것과 일치 하도록 getObject 메소드를 변경하는 것입니다. 필자의 경우 원래 getImageUrl이 있었지만 JSON 데이터에는 image_url 이있어 매퍼를 버렸습니다. 내 setter와 getter를 getImage_url 및 setImage_url로 변경했습니다 .

도움이 되었기를 바랍니다.


원하는 이름이 xxx_yyy 인 경우 호출 방법은 getXxx_yyy 및 setXxx_yyy입니다. 이것은 매우 이상하지만 작동합니다.
sivi

3

POJO는 다음과 같이 정의되어야합니다.

응답 클래스

public class Response {
    private List<Wrapper> wrappers;
    // getter and setter
}

래퍼 클래스

public class Wrapper {
    private String id;
    private String name;
    // getters and setters
}

그리고 가치를 읽는 매퍼

Response response = mapper.readValue(jsonStr , Response.class);

거의. 아니 wrappers,하지만 wrapper.
Frans

@Frans Haha, 오류를 잡아 주셔서 감사합니다. 나는 자연스럽게 컬렉션에 복수를 사용합니다. 그러나 OP의 질문에 따르면 단수이어야합니다.
Dino Tw

3

이것은 매우 늦은 응답 일 수 있지만 POJO를 이것으로 변경하면 문제에 제공된 json 문자열이 해결됩니다 (입력 문자열이 말한 것처럼 제어 할 수 없기 때문에).

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}

3

또 다른 가능성은 application.properties의이 특성으로, 애플리케이션 spring.jackson.deserialization.fail-on-unknown-properties=false에서 다른 코드를 변경할 필요가 없습니다. 계약이 안정적이라고 판단되면이 속성을 제거하거나 사실로 표시 할 수 있습니다.


3

이것은 OP와 같은 문제가 아닐 수도 있지만 누군가 내가했던 것과 같은 실수로 여기에 왔을 때 문제를 해결하는 데 도움이 될 것입니다. JsonProperty 주석과 다른 종속성에서 ObjectMapper를 사용할 때 OP와 동일한 오류가 발생했습니다.

이것은 작동합니다 :

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;

작동하지 않습니다 :

import org.codehaus.jackson.map.ObjectMapper; //org.codehaus.jackson:jackson-mapper-asl:1.8.8
import com.fasterxml.jackson.annotation.JsonProperty; //com.fasterxml.jackson.core:jackson-databind:2.2.3

감사! import com.fasterxml.jackson.annotation.JsonProperty는 저 대신에 저를 위해 일했습니다 :-)
phil

2

구글은 여기에 날 데려와 나는이 답변을보고 놀랐습니다 ... 모든 제안 우회 (오류 항상 developement에 4 개 주름 나중에 다시 물린 오히려까지 해결보다) 이 신사 SO에 믿음으로 복원을!

objectMapper.readValue(responseBody, TargetClass.class)

JSON 문자열을 클래스 객체로 변환하는 데 사용되며 누락 된 것은 TargetClasspublic getter /set ters 입니다. OP의 질문 스 니펫에서도 마찬가지입니다! :)

롬복을 통해 아래와 같이 수업이 진행됩니다 !!

@Data
@Builder
public class TargetClass {
    private String a;
}

2

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

짤방 백업 봇


어쩌면 추가 설명이나 문서가 좋을 것입니다.
Benj

@JsonIgnoreProperties (ignoreUnknown = true) 감사합니다
Guilherme
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.