ジャクソン(JSON)でのシリアライズ-「シリアライザが見つかりません」と表示されますか?


262

ジャクソンを使用して非常に単純なオブジェクトをシリアル化しようとすると、例外が発生します。エラー:

org.codehaus.jackson.map.JsonMappingException:クラスMyPackage.TestAのシリアライザーが見つからず、BeanSerializerを作成するためのプロパティが見つかりません(例外を回避するには、SerializationConfig.Feature.FAIL_ON_EMPTY_BEANSを無効にします)

以下は、シリアル化する単純なクラスとコードです。

誰かがこのエラーが発生する理由を教えていただけますか?

public class TestA {
    String SomeString = "asd";
}

TestA testA = new TestA();
ObjectMapper om = new ObjectMapper();
try {
    String testAString = om.writeValueAsString(testA); // error here!

    TestA newTestA = om.readValue(testAString, TestA.class);
} catch (JsonGenerationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

私は、Jacksonカスタムシリアライザーを作成する方法に関する投稿を書きました。
Sam Berry

回答:


329

すでに説明したように、ObjectMapperインスタンスのデフォルト構成は、パブリックフィールドであるプロパティ、またはパブリックゲッター/セッターを持つプロパティのみにアクセスすることです。クラス定義を変更してフィールドをパブリックにするか、パブリックゲッター/セッターを提供する代わりにVisibilityChecker、別のプロパティの可視性ルールを(基になるに)指定することもできます。ジャクソン1.9はObjectMapper.setVisibility()そうするための便利な方法を提供します。元の質問の例では、おそらくこれを次のように構成します

myObjectMapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);

ジャクソン> 2.0の場合:

myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

関連する構成オプションの詳細と詳細については、JavaDocsObjectMapper.setVisibility()を確認することをお勧めます。


59
これでうまくいきました。Jackson 2.0以降、ObjectMapper#setVisibilityは最初の引数としてPropertyAccessorを取ります。同等のワンライナーはmyObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
Dan Robinson

@DanRobinson私も同じものを使いました。しかし、実際にはyamlファイルを生成しています。JSONStringの場合:{"term":{"call_failed":"true"}}yaml構造を生成しています:filter: map: term: map: call_failed: "true"なぜmapキーワードを生成しているのですか?どうすれば削除できますか?
Manish Kumar

7
私はおそらく私のgetterメソッドがit..so愚かに「公共」を持っていなかったことを実現していない、このエラーで8時間を過ごした
マイク・ケロッグ

1
オブジェクトマッパーを使用してClientResponseを文字列に変換するときにこのエラーが発生します
VdeX

1
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)クラスの上に注釈を追加することもできます
veben

74

ジャクソンがそのクラスをシリアル化するには、SomeStringフィールドがpublic(現時点ではパッケージレベルの分離である)か、そのフィールドのゲッターメソッドとセッターメソッドを定義する必要があります。


5
この回答は正しくないことに注意してください。フィールドはパブリックである必要はなく、ゲッターとセッターを持つ必要ありません。この質問に対する別の答えとして、元のデータ構造を変更して(逆)シリアル化する必要のない代替構成を提供しました。
プログラマーBruce

9
100%正確ではない場合でも、答えは役に立ちます。私は自分の変数に「公開」することを忘れていましたが、これはそれを指摘しました。ありがとう!
ChrisPhoenix、2015

54

ソースコードにも同じ問題があります。追加したばかりです

ゲッター

そして

セッター

問題は解決しました。


1
多くの異なるものを試してみましたが、解決策はこれと同じくらい簡単です...そしてそれは非常にはっきりと言っています:「作成するプロパティが見つかりませんでした」。
2018

2
@PhilipRego彼は、フィールドのゲッターとセッターを追加したことを意味します。
ポール

私はロンボク・ライブラリーを使用しているので、注釈ゲッターとセッターを追加するだけです。そして、すべてが大丈夫だった。ありがとう。
Rahmat Hidayat

そう、ゲッターとセッターはジャクソンのシリアライゼーションに使用されます
。/デ

25

私の場合の問題は、ジャクソンが属性もメソッドもない空のオブジェクトをシリアル化しようとしていたことでした。

例外で提案されているように、空のBeanでの失敗を回避するために次の行を追加しました。

ジャクソン1.9の場合

myObjectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

ジャクソン2.X

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

jackson disable fail_on_empty_beansの簡単な例を見つけることができます


9

私が制御していた子クラスでも同じ問題があり、オブジェクトマッパーは共通モジュール内にあり、アクセスできませんでした。オブジェクトをシリアル化する子クラスにこのアノテーションを追加することで解決しました。

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

7

そのオブジェクトを含むクラスを編集できる場合、通常は注釈を追加します

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;

2
このエラーは、クラスにgetで始まる名前のメソッドがある場合にも発生します...たとえば、NonSerializableClass getMyNonSerializableObject()。ジャクソンはそれをシリアライズしようとして失敗します。この問題を解決するには、@ JsonIgnoreを追加するか、メソッドの名前を変更します。
Alexey Podlasov 2015年

1
古いバージョンを使用:org.codehaus.jackson.annotate.JsonIgnore
AlikElzin-kilaka

6

このエラーは、.build()メソッドを戻りステータスに追加し忘れた場合にもスローされます。

return Response.status(Status.OK);         // fails
return Response.status(Status.OK).build(); // works

build()メソッドなしで次のエラーが発生しました。

org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.sun.jersey.core.spi.factory.ResponseBuilderImpl

4

SpringBoot2.0、以下のコードで解決します:

@Bean public ObjectMapper objectMapper() {
 return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);}

1
モデルにゲッターメソッドとセッターメソッドを持たせる必要があります。
Janus

1
SOへようこそ!貢献してくれてありがとう。解答に説明を追加してください。そうすれば、コードが何をするのか、なぜ機能するのか、OPsの質問にどのように答えるのかが明確になります。
Max Vollmer 2018

これは私を助けました!しかし、私の意見では、新しいObjectMapperを作成するのではなく、コンテキストのObjectMapperを挿入して、後で構成する必要があります。
RoBeaToZ

3

Oracle Javaアプリケーションの場合、ObjectMapperインスタンス化の後にこれを追加します。

mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

2

hibernateプロキシオブジェクトを介した遅延読み込みで同様の問題が発生しました。遅延読み込みされたプライベートプロパティを持つクラスに次のアノテーションを付けることで、問題を回避できます。

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

これは私の問題を解決しました。これが正確に何をしているのか教えてもらえますか?
スカーフェイス2017

2

変数をとして宣言したことが原因である可能性がありますprivate。に変更するとpublic、機能します。

より良いオプションは、getterメソッドとsetterメソッドを使用することです。

これで問題が解決します!


2

私はこれを行う少なくとも3つの方法を見つけました。

  1. public gettersシリアル化しようとするエンティティを追加します。
  2. 必要がない場合は、エンティティの上部に注釈を追加しますpublic getters。これは、からジャクソンのデフォルトを変更しますVisbility=DEFAULTへの@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)任意のアクセス修飾子を受け入れているところ。
  3. ObjectMapper設定して、グローバルに変更しますobjectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);。この機能をグローバルに必要としない場合は、これを回避する必要があります。

必要に応じて選択してください。


2

3つのオプションは次のとおりです。

  1. アクセスされたデータ/クラスは public
  2. そうでない場合はpublicゲッターとセッターを追加します
  3. または追加 @JsonIgnore("context")

1

Beanのクラスレベルでこれを使用してください:

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})

1

セッターとゲッターを追加すると、問題が解決します。例:

public class TestA {
    String SomeString = "asd";

    public String getSomeString () {        return SomeString ;     }

    public void setSomeString (String SS ) {        SomeString = SS ;   } 
}


0

ゲッターとセッターを追加しましたが、同じエラーが発生しました。後でバグを発見しました。これは、ソナーのアドバイスにより、ゲッターとセッターを保護されていると見なして問題を引き起こしていたためです。修正したら、期待どおりに機能した。


0

春のブーツで2.2.5

ゲッターとセッターを追加した後

フィールドの上に@JsonIgnoreを追加しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.