ジャクソンがフィールドのみを使用するように指定する方法-できればグローバルに


189

デフォルトのジャクソン動作は、jsonへのシリアル化と逆シリアル化にプロパティ(ゲッターとセッター)とフィールドの両方を使用するようです。

フィールドをシリアル化構成の標準的なソースとして使用したいので、Jacksonにプロパティをまったく表示させたくありません。

これは、アノテーションを使用して個々のクラスごとに行うことができます。

 @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)

しかし、私はこれをすべてのクラスに置く必要はありません...

これをグローバルに構成することは可能ですか?オブジェクトマッパーにいくつか追加したいですか?


1
ティムは良い答えを出しました。もう1つの可能性は、共通の基本クラスがある場合、そのクラスにクラス注釈を付けることができることです。注釈はジャクソンによって継承されます。
StaxMan 2011

1
私はそれを試したと思いますが、基本クラスが定義するものを使用するようにサブクラスに指示する必要があるようです...
Michael Wiles '19

2
いいえ、サブクラスがクラスアノテーションをオーバーライドしない限り、親のアノテーションはサブクラス定義の一部であるかのように表示されます(そうでない場合、これはバグです)。これは必ずしもJDKがアノテーションを処理する方法ではありませんが、Jacksonはアノテーション(メソッドアノテーションの場合でも)の完全な継承を実装しています。
StaxMan 2011

INFER_PROPERTY_MUTATORS旗に注意してください。可視のゲッターまたはフィールドがある場合、セッターの可視性を強制します。
OndraŽižka18年

回答:


157

次のように、個々のObjectMapperを構成できます。

ObjectMapper mapper  = new ObjectMapper();
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));

グローバルに設定する場合は、通常、ラッパークラスを介して構成済みマッパーにアクセスします。


3
良いですが、チェッカーも設定する必要があると思います(withXxx()メソッドは通常、新しいオブジェクトを作成します)。したがって、「mapper.setVisibilityChecker(mapper.getVisibilityChecker()。with ...);」のようなもの
StaxMan 2011

@StaxManはsetVisibilityCheckerをよろしくお願いします。答えを編集して反映しました。
Kevin Bowersox、2009

42
withGetterVisibilityis*メソッドについては説明しませんが、メソッドwithIsGetterVisibilityについては説明します。
qerub

13
setVisibilityChecker廃止予定です。setVisibility代わりに使用してください。
0x7d7b 2016

1
これはまさに私が必要としたものです!この構成により、Mixinを使用してHibernateエンティティをDTOに簡単に変換できました。デフォルトでは、ObjectMapperはすべてをシリアル化し、Mixinは無視するプロパティ(つまり、交差ではなく減算)を指定する必要があります。
TastyWheat

150

ジャクソン2.0以降では、次のように簡単に使用できます。

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;   

...

ObjectMapper mapper = new ObjectMapper();    
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

自動検出をオフにします。


1
こんにちは、私はジャクソン1.9.0 jarを使用しています。オブジェクトをjson文字列にシリアル化しながら、追加のjsonプロパティを取得しています。@JsonPropertyで言及された変数のみを含むjson文字列を取得する必要があります。これについて私を助けてくれませんか?
jrhamza 2013年

7
OPの質問で言及されているクラスアノテーションから開始でき@JsonAutoDetect(fieldVisibility = Visibility.NONE, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)ます。次に、含めるプロパティごとにアノテーションを付ける必要があります@JsonProperty
lukk

ありがとう!以前、PropertyAccessorの代わりにJsonMethodが参照されている多くのコード例を見つけました。JsonMethodを検索した場合、PropertyAccessorへのリンクはめったにありません...後続のアーティファクトで置換クラス名を見つけるための最良の方法は何ですか?タフで嫌なことができますか?
philburns

38

具体的には boolean is*()ゲッターについて:

私は多くの時間を費やしてきました

  @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)

これも

  setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
  setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
  setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

私のブールゲッター/セッターのために働いた。

解決策は簡単です:

  @JsonAutoDetect(isGetterVisibility = Visibility.NONE, ...          
  setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);

更新:スプリングブートで構成可能:

jackson:
  visibility.field: any
  visibility.getter: none
  visibility.setter: none
  visibility.is-getter: none

参照してください一般的なアプリケーションのプロパティ#JACKSON


1
簡単なソリューションをBeanクラスに適用する方法を詳しく説明してください。
Pavel Niedoba 2016年

1
ありがとうございました。つまり、Getterがその日を助けてくれました。
2017年

これは質問に対する答えではなく、誤解を招く可能性があります。
OndraŽižka18年

14

ジャクソン1.9.10の場合

ObjectMapper mapper = new ObjectMapper();

mapper.setVisibility(JsonMethod.ALL, Visibility.NONE);
mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);

自動検出をオフにします。


2
それが方法です。ありがとう。
cuneytykaya 14

これを行うことと「自動検出」を無効にすることの間に違いがあるかどうか疑問に思います。
xenoterracide 2016年

10

これはどうですか:私はミックスインで使用しました

非準拠オブジェクト

@Entity
@Getter
@NoArgsConstructor
public class Telemetry {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long pk;
    private String id;
    private String organizationId;
    private String baseType;
    private String name;
    private Double lat;
    private Double lon;
    private Instant updateTimestamp;
}

混入します:

@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
public static class TelemetryMixin {}

使用法:

    ObjectMapper om = objectMapper.addMixIn(Telemetry.class, TelemetryMixin.class);
    Telemetry[] telemetries = om.readValue(someJson, Telemetry[].class);

いくつものクラスを予見できず、同じミックスインを適用できないと言っていることは何もありません。

あなたがミックスインに慣れていない場合、彼らは単に概念的には:ミックスインの構造がされてスーパー課さ(限りJVMに関しては、ジャクソンによらない)ターゲットクラスに。


3

の構成を気にせずにこれをグローバルに行う方法が必要なObjectMapper場合は、独自の注釈を作成できます。

@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonAutoDetect(
        getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
        setterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE,
        creatorVisibility = JsonAutoDetect.Visibility.NONE
)
public @interface JsonExplicit {
}

これで、クラスに注釈を付けるだけ@JsonExplicitでいいのです。

また、上記の呼び出しを編集@JsonAutoDetectして、プログラムで機能する値に値が設定されていることを確認してください。

https://stackoverflow.com/a/13408807のクレジットを取得して、@JacksonAnnotationsInside


3

Spring Bootを使用する場合は、次のようにJacksonをグローバルに構成できます。

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonObjectMapperConfiguration implements Jackson2ObjectMapperBuilderCustomizer {

    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.visibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
        jacksonObjectMapperBuilder.visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        jacksonObjectMapperBuilder.visibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY);
    }

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