web-dev-qa-db-ja.com

JSONのあるジャクソン:認識できないフィールド、無視できるものとしてマークされていない

特定のJSON文字列をJavaオブジェクトに変換する必要があります。私はJSON処理にJacksonを使用しています。入力JSONを制御できません(私はWebサービスから読み取ります)。これは私の入力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
}

私のWrapperクラスは基本的に私の学生のリストを取得するためのコンテナオブジェクトです。

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

私はこのエラーが出続け、 "wrapper"は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)
541
jshree

Jacksonのクラスレベルのアノテーションを使うことができます。

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

POJOで定義していないすべてのプロパティは無視されます。 JSONでいくつかのプロパティを探していて、マッピング全体を書きたくない場合に非常に便利です。 Jacksonのウェブサイト でさらなる情報。宣言されていないプロパティを無視したい場合は、次のように書きます。

@JsonIgnoreProperties(ignoreUnknown = true)
832
Ariel Kogan

あなたが使用することができます

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

宣言されていないすべてのプロパティは無視されます。

390

最初の答えはほぼ正しいですが、必要なのはフィールドではなくゲッターメソッドを変更することです - フィールドはプライベートです(そして自動検出されません)。さらに、両方が表示されている場合は、ゲッターがフィールドよりも優先されます(プライベートフィールドを表示する方法もありますが、ゲッターを使用する場合はあまり意味がありません)。

そのため、getterはgetWrapper()という名前にするか、次のように注釈を付けてください。

@JsonProperty("wrapper")

そのままgetterメソッド名を好む場合。

117
StaxMan

jackson 2.6.0を使用して、これは私のために働きました:

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

と設定で:

@JsonIgnoreProperties(ignoreUnknown = true)
74
Scott

それは2つの方法で達成できます。

  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) 
    
44
Amit Kaneria

これは私にとっては完璧に機能した

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

@JsonIgnoreProperties(ignoreUnknown = true)アノテーションはしませんでした。

39
Felix Kimutua

これは、Allよりもうまく機能します。このプロパティを参照してください。

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);
35
Karan

Jackson 2.0を使用している場合

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

doc によると、選択したフィールドまたはすべての未知のフィールドを無視することができます。

 // 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)
17
tomrozb

それは私のために次のコードでうまくいきました:

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

JacksonはあなたのクラスのWrapperに "wrapper"と呼ばれるフィールドが見つからないので文句を言っています。あなたのJSONオブジェクトは "wrapper"と呼ばれるプロパティを持っているのでこれはそうしています。

Wrapperクラスのフィールドの名前を "Students"ではなく "wrapper"に変更することで解決すると思います。

12
Jim Ferrans

この解決策は、JSONストリームを読み取るときに一般的であり、いくつかのフィールドのみを取得する必要があるのに対して、ドメインクラスで正しくマップされていないフィールドは無視できます。

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

詳細な解決策は、jsonschema2pojoなどのツールを使用して、json応答のスキーマからStudentなどの必要なドメインクラスを自動生成することです。あなたはスキーマコンバータへの任意のオンラインJSONによって後者を行うことができます。

10

私は以下の方法を試してみました、そしてそれはJacksonでそのようなJSONフォーマットの読書のために働きます。既に提案されている解決策を使用してください:@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 を参照してください。

お役に立てれば

10
mytwocentsads

JsonプロパティとJavaプロパティの名前に不一致があるため、次のようにフィールドStudentsに注釈を付けます。

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

誰も言及していないように、私はそう思った….

問題はあなたのJSONのあなたの財産は「ラッパー」と呼ばれ、Wrapper.classのあなたの財産は「学生」と呼ばれることです。

だからどちらか...

  1. クラスまたはJSONのいずれかでプロパティの名前を修正してください。
  2. StaxManのコメントに従って、プロパティ変数に注釈を付けます。
  3. セッターに注釈を付けます(あなたが持っている場合)
8
TedTrippin

どちらかの変更

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
sagar

あなたの入力

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

これがObjectであることを示し、 "wrapper"という名前のフィールドを持ちます。これは、生徒のコレクションです。だから私のお勧めは、

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

Wrapperは次のように定義されています。

class Wrapper {
    List<Student> wrapper;
}
5
Ran0990BK

私のために働いたのは、財産を公にすることでした。それは私のために問題を解決しました。

4
Rohitesh

これは私のために完璧に働いた

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
4
Niamath

POJOクラスの設定メソッドと取得メソッドのシグネチャを変更するだけで、この問題を解決しました。私がしなければならなかったのは、マッパーが探していたものと一致するように getObject メソッドを変更することだけでした。私の場合は、元々 getImageUrl を持っていましたが、JSONデータは image_url を持っていたため、マッパーは使用できません。セッターとゲッターの両方を getImage_urlとsetImage_url に変更しました。

お役に立てれば。

4
superuserdo

私の側では、唯一の行

@JsonIgnoreProperties(ignoreUnknown = true)

うまくいきませんでした。

追加するだけ

@JsonInclude(Include.NON_EMPTY)

ジャクソン2.4.0

4
jodu

public あなたのクラスフィールドを private に設定しないでください。

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

新しいFirebase Androidはいくつかの大きな変更をもたらしました。ドキュメントのコピーの下に:

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

あなたのJavaモデルオブジェクトを更新する

2.x SDKと同様に、Firebase Databaseは、DatabaseReference.setValue()に渡すJavaオブジェクトを自動的にJSONに変換し、DataSnapshot.getValue()を使用してJSONをJavaオブジェクトに読み込むことができます。

新しいSDKでは、DataSnapshot.getValue()を使用してJSONをJavaオブジェクトに読み込むとき、JSON内の不明なプロパティがデフォルトで無視されるようになったため、@JsonIgnoreExtraProperties(ignoreUnknown=true)は不要になりました。

JSONにJavaオブジェクトを書き込むときにフィールド/ゲッターを除外するために、アノテーションは@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)

あなたのJavaクラスにはないあなたのJSONに追加のプロパティがある場合、あなたはログファイルにこの警告を見るでしょう:

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

クラスに@IgnoreExtraPropertiesアノテーションを付けることでこの警告を取り除くことができます。 Firebase Databaseが2.x SDKと同じように動作し、未知のプロパティがある場合に例外をスローするようにしたい場合は、クラスに@ThrowOnExtraPropertiesアノテーションを付けることができます。

3
ThierryC

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);
3
Dino Tw

これは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
2
cwa

これは非常に遅い応答かもしれませんが、POJOをこれに変更するだけで、問題で提供されているjson文字列が解決されるはずです(あなたが言ったように入力文字列はあなたのコントロールにないからです):

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

グーグルはここに私を連れて来て私は答えを見て驚いた...すべての提案 迂回 エラー( 開発までの4倍後に噛み付く )まで解決するのではなく この紳士 SOへの信仰によって回復された!

objectMapper.readValue(responseBody, TargetClass.class)

json Stringをクラスオブジェクトに変換するために使用されますが、TargetClassはpublic getter/settersを持つべきであるということが欠けています。 OPの質問スニペットにも同じことがありません。 :)

下記のように lombok /あなたのクラスは動作するはずです!

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

私の場合は簡単でした。RESTサービスのJSONオブジェクトは更新されました(プロパティが追加されました)が、RESTクライアントのJSONオブジェクトは更新されませんでした。私がJSONクライアントオブジェクトを更新するとすぐに、 '認識できないフィールド...'例外が消えました。

1
blue-bird

もう1つの可能性は、application.properties spring.jackson.deserialization.fail-on-unknown-properties=false内のこのプロパティです。アプリケーション内で他のコードを変更する必要はありません。そして、契約が安定していると思われる場合は、この物件を削除するか、またはtrueとマークすることができます。

1
krmanish007

Wrapperクラスをに変更

public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

これがすることは、jsonオブジェクトのstudentsキーとしてwrapperフィールドを認識することです。

また、私は個人的に Lombok Annotations をGettersおよびSetterに使用することを好みます。

@Getter
@Setter
public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

私はLombokと@JsonPropertyを一緒に使って上記のコードをテストしていないので、LombokのデフォルトのgetterとsetterをオーバーライドするためにWrapperクラスに次のコードを追加することをお勧めします。

public List<Student> getWrapper(){
     return students;
}

public void setWrapper(List<Student> students){
     this.students = students;
}

Jacksonを使ってリストをデシリアライズするには this outもチェックしてください。

0

私の場合、以下の理由でエラーが発生しました

  • 最初はうまくいっていました、それから私は1つの変数の名前を変更し、コードを変更しました、そしてそれは私にこのエラーを与えました。

  • それから私もジャクソンの無知な性質を適用しました、しかしそれはうまくいきませんでした。

  • 最後に私の変数の名前に従って私の取得メソッドと設定メソッドを再定義した後、このエラーは解決されました

そのため、ゲッターとセッターも必ず再定義してください。

0
Vikram Saini

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties

0
Gank

Listのフィールドを "Students"から "wrapper"に変更するだけで、jsonファイルだけが検索されます。

0
Troy

あなたのJSON文字列は、マッピングされたクラスとインラインではありません。入力文字列を変更する

String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";

またはマッピングされたクラスを変更する

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