特定の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)
Jacksonのクラスレベルのアノテーションを使うことができます。
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties
class { ... }
POJOで定義していないすべてのプロパティは無視されます。 JSONでいくつかのプロパティを探していて、マッピング全体を書きたくない場合に非常に便利です。 Jacksonのウェブサイト でさらなる情報。宣言されていないプロパティを無視したい場合は、次のように書きます。
@JsonIgnoreProperties(ignoreUnknown = true)
あなたが使用することができます
ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
宣言されていないすべてのプロパティは無視されます。
最初の答えはほぼ正しいですが、必要なのはフィールドではなくゲッターメソッドを変更することです - フィールドはプライベートです(そして自動検出されません)。さらに、両方が表示されている場合は、ゲッターがフィールドよりも優先されます(プライベートフィールドを表示する方法もありますが、ゲッターを使用する場合はあまり意味がありません)。
そのため、getterはgetWrapper()
という名前にするか、次のように注釈を付けてください。
@JsonProperty("wrapper")
そのままgetterメソッド名を好む場合。
jackson 2.6.0を使用して、これは私のために働きました:
private static final ObjectMapper objectMapper =
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
と設定で:
@JsonIgnoreProperties(ignoreUnknown = true)
それは2つの方法で達成できます。
未知のプロパティを無視するようにPOJOにマークを付ける
@JsonIgnoreProperties(ignoreUnknown = true)
以下のように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)
これは私にとっては完璧に機能した
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@JsonIgnoreProperties(ignoreUnknown = true)
アノテーションはしませんでした。
これは、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);
Jackson 2.0を使用している場合
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
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)
それは私のために次のコードでうまくいきました:
ObjectMapper mapper =new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JacksonはあなたのクラスのWrapperに "wrapper"と呼ばれるフィールドが見つからないので文句を言っています。あなたのJSONオブジェクトは "wrapper"と呼ばれるプロパティを持っているのでこれはそうしています。
Wrapperクラスのフィールドの名前を "Students"ではなく "wrapper"に変更することで解決すると思います。
この解決策は、JSONストリームを読み取るときに一般的であり、いくつかのフィールドのみを取得する必要があるのに対して、ドメインクラスで正しくマップされていないフィールドは無視できます。
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
詳細な解決策は、jsonschema2pojoなどのツールを使用して、json応答のスキーマからStudentなどの必要なドメインクラスを自動生成することです。あなたはスキーマコンバータへの任意のオンラインJSONによって後者を行うことができます。
私は以下の方法を試してみました、そしてそれは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 を参照してください。
お役に立てれば
JsonプロパティとJavaプロパティの名前に不一致があるため、次のようにフィールドStudentsに注釈を付けます。
public Class Wrapper {
@JsonProperty("wrapper")
private List<Student> students;
//getters & setters here
}
誰も言及していないように、私はそう思った….
問題はあなたのJSONのあなたの財産は「ラッパー」と呼ばれ、Wrapper.classのあなたの財産は「学生」と呼ばれることです。
だからどちらか...
どちらかの変更
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"}]}
あなたの入力
{"wrapper":[{"id":"13","name":"Fred"}]}
これがObjectであることを示し、 "wrapper"という名前のフィールドを持ちます。これは、生徒のコレクションです。だから私のお勧めは、
Wrapper = mapper.readValue(jsonStr , Wrapper.class);
Wrapper
は次のように定義されています。
class Wrapper {
List<Student> wrapper;
}
私のために働いたのは、財産を公にすることでした。それは私のために問題を解決しました。
これは私のために完璧に働いた
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
POJOクラスの設定メソッドと取得メソッドのシグネチャを変更するだけで、この問題を解決しました。私がしなければならなかったのは、マッパーが探していたものと一致するように getObject メソッドを変更することだけでした。私の場合は、元々 getImageUrl を持っていましたが、JSONデータは image_url を持っていたため、マッパーは使用できません。セッターとゲッターの両方を getImage_urlとsetImage_url に変更しました。
お役に立てれば。
私の側では、唯一の行
@JsonIgnoreProperties(ignoreUnknown = true)
うまくいきませんでした。
追加するだけ
@JsonInclude(Include.NON_EMPTY)
ジャクソン2.4.0
public あなたのクラスフィールドを private に設定しないでください。
public Class Student {
public String name;
public String id;
//getters & setters for name & id here
}
新しい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
アノテーションを付けることができます。
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);
これは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
これは非常に遅い応答かもしれませんが、POJOをこれに変更するだけで、問題で提供されているjson文字列が解決されるはずです(あなたが言ったように入力文字列はあなたのコントロールにないからです):
public class Wrapper {
private List<Student> wrapper;
//getters & setters here
}
グーグルはここに私を連れて来て私は答えを見て驚いた...すべての提案 迂回 エラー( 開発までの4倍後に噛み付く )まで解決するのではなく この紳士 SOへの信仰によって回復された!
objectMapper.readValue(responseBody, TargetClass.class)
json Stringをクラスオブジェクトに変換するために使用されますが、TargetClass
はpublic get
ter/set
tersを持つべきであるということが欠けています。 OPの質問スニペットにも同じことがありません。 :)
下記のように lombok /あなたのクラスは動作するはずです!
@Data
@Builder
public class TargetClass {
private String a;
}
私の場合は簡単でした。RESTサービスのJSONオブジェクトは更新されました(プロパティが追加されました)が、RESTクライアントのJSONオブジェクトは更新されませんでした。私がJSONクライアントオブジェクトを更新するとすぐに、 '認識できないフィールド...'例外が消えました。
もう1つの可能性は、application.properties spring.jackson.deserialization.fail-on-unknown-properties=false
内のこのプロパティです。アプリケーション内で他のコードを変更する必要はありません。そして、契約が安定していると思われる場合は、この物件を削除するか、またはtrueとマークすることができます。
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もチェックしてください。
私の場合、以下の理由でエラーが発生しました
最初はうまくいっていました、それから私は1つの変数の名前を変更し、コードを変更しました、そしてそれは私にこのエラーを与えました。
それから私もジャクソンの無知な性質を適用しました、しかしそれはうまくいきませんでした。
最後に私の変数の名前に従って私の取得メソッドと設定メソッドを再定義した後、このエラーは解決されました
そのため、ゲッターとセッターも必ず再定義してください。
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties
Listのフィールドを "Students"から "wrapper"に変更するだけで、jsonファイルだけが検索されます。
あなたのJSON文字列は、マッピングされたクラスとインラインではありません。入力文字列を変更する
String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
またはマッピングされたクラスを変更する
public class Wrapper {
private List<Student> wrapper;
//getters & setters here
}