web-dev-qa-db-ja.com

Jacksonが@JsonPropertyでGetterをオーバーライドしない

JsonPropertyは、gacksonがゲッターから取得するデフォルトの名前をオーバーライドしていません。以下のクラスをObjectMapperとjacksonでシリアル化すると、

{"hi":"hello"}

ご覧のとおり、JsonPropertyアノテーションは効果がありません

class JacksonTester {
    String hi;

    @JsonProperty("hello")
    public String getHi() {
        return hi;
    }
}   

置く@JsonProperty文字列自体も機能しません。名前を変更できるように見える唯一の方法は、ゲッターの名前を変更することです。唯一の問題は、最初の文字では常に小文字になることです

13
tt_Gantz

問題は、古いジャクソンライブラリと新しいジャクソンライブラリの両方を使用していたことです。

つまり、import org.codehaus.jackson.annotate.JsonProperty;使用していたライブラリと一致させるために、以下に変更する必要がありました。

私はMavenを使用していたので、Mavenの依存関係を更新することも意味していました。 import com.fasterxml.jackson.annotation.JsonProperty;

それが機能するためには、@JsonPropertyゲッターの注釈(オブジェクトに設定しても機能しませんでした)

私はここで答えを見つけました(francescoforestiに感謝) @ JsonPropertyが期待どおりに機能しない

29
tt_Gantz

FasterXML Jacksonの古いバージョンから2.8.3に更新するときにこの問題が発生しました。

問題は、DBからのJSON応答をJavaクラスオブジェクトにデシリアライズするとき、コードのクラスのセッターに_@JsonSetter_がなかったためです。したがって、シリアライズするとき、出力は「クラスを利用しない」ゲッターはJavaクラスオブジェクトをJSONにシリアル化します(したがって、@JsonProperty()デコレーターは有効になりませんでした)。

そのプロパティのセッターメソッドに@JsonSetter("name-from-db")を追加することで問題を修正しました。

また、@JsonProperty()の代わりに、getterメソッドを使用してプロパティの名前を変更するために、プロパティの名前変更に固有の@JsonGetter()を使用できます。

コードは次のとおりです。

_public class KwdGroup {
    private String kwdGroupType;

    // Return "type" instead of "kwd-group-type" in REST API response
    @JsonGetter("type") // Can use @JsonProperty("type") as well
    public String getKwdGroupType() {
        return kwdTypeMap.get(kwdGroupType);
    }

    @JsonSetter("kwd-group-type") // "kwd-group-type" is what JSON from the DB API outputs for code to consume 
    public void setKwdGroupType(String kwdGroupType) {
        this.kwdGroupType = kwdGroupType;
    }
}
_
4
Xchai

Kotlinを使用している場合

元々の質問はJavaにあると理解していますが、Kotlinは非常に人気があり、多くの人がそれを使用している可能性があるため、他の人を助けるためにここに投稿したいと思います。

とにかく、Kotlinの場合、ゲッター/セッターがどのように機能するか、valを使用している場合、つまりゲッターのみを公開する場合、以下のようにゲッターに注釈を適用する必要があります。

class JacksonTester(@get:JsonProperty("hello") val hi: String)

2
Francisco C.

私は同じ問題を抱えていた

Import import com.fasterxml.jackson.annotation.JsonPropertyを置き換えるだけです。インポート時org.codehaus.jackson.annotate.JsonProperty;その仕事。

2
Dmitriy S

適切な注釈を定義した後でも、ラクダのケースにはまだ問題があるようです。例:

@JsonProperty( "mirrorport")private String mirrorPort;

Xmlに<mirrorport>YES</mirrorport>がある場合、逆シリアル化は依然として失敗します

1
gpushkas

私は最近、この問題に関する別の興味深いひねりに出会いました。遅延読み込みの問題を解決するために、Hibernate5Moduleの使用を開始しました。さらに、Groovyを使用しているため、ゲッターとセッターを定義していません。

Hibernate Moduleは@JsonPropertyアノテーションに干渉しているようです。具体的には、@Transientで注釈が付けられているものがある場合、次のようなものがある場合:

@Transient
@ApiModelProperty(required = true)
@JsonProperty("alternateName")
String property

JSONにalternateNameは表示されません。さらに、クライアントはおそらくPOSTとPUTで問題を抱えています。これを修正するには、簡単な回避策を使用できます。使用する必要がある内部名のゲッターとセッターを定義し(*)、@JsonPropertyvalue属性を使用しないでください。

@Transient
@ApiModelProperty(required = true)
@JsonProperty
String alternateName

void setProperty(String property) {
    this.alternateName = property
}

@JsonIgnore
String getProperty() {
    this.alternateName
}

ゲッターでの@JsonIgnoreの使用に注意してください。そうしないと、フレームワークがそれを選択し、JSON内の同じものに対して重複したエントリが作成される可能性があります。

とにかく-これが誰かを助けることを願っています!

(*)特定のインターフェイスに準拠しようとしていたため、内部的に名前が強制されました。ただし、公開されたAPIには、別の使いやすい名前が必要でした。

1

以下を試しましたか

class JacksonTester {
    private String hi;

    @JsonProperty("hello")
    public String getHi() {
        return hi;
    }
}   

「hi」変数宣言をプライベートにすることを意味します。または、変数宣言に@JsonIgnoreを配置してみて、デフォルトのスコープで保持したい場合に備えてください。

0
vvs

データバインドの依存関係がありませんでした

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${fasterxml.version}</version>
</dependency>
0
ketankk

ゲッターではなく変数に配置します

class JacksonTester {
    @JsonProperty("hello")
    private String hi;

    public String getHi() {
        return hi;
    }
} 
0
mprivat