LoginSignup
1
0

JacksonのアノテーションをGsonでも(どうしても)利用したい時の対処

Last updated at Posted at 2023-12-05

JacksonGSONもJavaのオブジェクトとJSONを変換したいという要望に答えるものです。
Jacksonで使ってるアノテーションを、Gsonでも使いまわしたいという状況に(両方使うのがベストプラクティスではなさそうということは置いておいて)対処します。
この記事では、Java->JSONの変換、アノテーションは後述の2種類という条件に絞って記述します。

Jacksonでのアノテーションの使われ方

Jacksonでは@JsonProperty@JsonIgnore等のアノテーションを使って、JSONのプロパティに付ける名前を変えたり、無視したりといったことを制御できます。

例)プロパティの名前を変える
デフォルトで { "_first_name" : "Bob" } というJSONに変換されるが、アノテーションがあるので { "firstName" : "Bob" } になる。

public class Name {
  @JsonProperty("firstName")
  public String _first_name;
}

同様に@JsonIgnoreを付けたフィールドは変換の際に無視されます。

GSONでストラテジーを定める

Gsonではフィールドの命名、無視を「ストラテジー」で定義します。
@JsonProperty@JsonIgnoreにそれぞれ、ExclusionStrategyFieldNamingStrategyが対応しています(使用例)。

ということで、アノテーションを読み込んでストラテジーを定義してやればいいのです(という案がissueにありましたので、それを紹介しています)。

GsonBuilder gb = new GsonBuilder()
    // 命名方法を決める
	.setFieldNamingStrategy(field -> {
		final JsonProperty jp = field.getAnnotation(JsonProperty.class);
		if (Objects.isNull(jp)) {
			return FieldNamingPolicy.IDENTITY.translateName(field); // アノテーションない場合の命名方法
		}
		return jp.value(); // アノテーションの値をフィールド名に採用
	})
    // 無視するものを決める
	.addSerializationExclusionStrategy(new ExclusionStrategy() {
		@Override
		public boolean shouldSkipField(FieldAttributes field) {
			return Objects.nonNull(field.getAnnotation(JsonIgnore.class)); // フィールドにJsonIgnoreが設定されていたら無視
		}
		@Override
		public boolean shouldSkipClass(Class<?> clazz) {
			return Objects.nonNull(clazz.getAnnotation(JsonIgnore.class)); // クラス単位でも無視するかを決める(使ってない場合でもOverrideが必要(なはず))
		}
	});

ただし、Gsonにも@SerializedName, @Exposeのアノテーションが用意されているので、完全にJacksonから移行できたらそちらを使いたいところです(@Expose@JsonIgnoreと逆の使い方なのでややこしいですが)。

参考

GsonのNamingについて、ポリシーを設定することもできる-> https://github.com/google/gson/blob/main/UserGuide.md#json-field-naming-support

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0