Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaのJacksonで@JsonAliasを使ってフィールドの代替名(エイリアス)を定義する方法

@JsonAliasアノテーションとは?

Jacksonの@JsonAliasアノテーションを使用すると、JSONデータをJavaオブジェクトへマッピングする際(デシリアライズ時)に受け入れ可能なプロパティに対して、1つ以上の代替名(エイリアス)を定義できます。

一方で、シリアライズ時(JavaオブジェクトからJSONを生成する場合)には、エイリアスは使用されず、実際の論理プロパティ名のみが出力される点に注意が必要です。

  • デシリアライズ時: 本来のプロパティ名と、@JsonAliasで指定した別名のどちらでもJSONを受け取れる
  • シリアライズ時: @JsonPropertyで指定した正式なプロパティ名のみが出力される
  • このアノテーションはJackson 2.9以降で利用可能

構文

@Target(value={ANNOTATION_TYPE,FIELD,METHOD,PARAMETER})
@Retention(value=RUNTIME)
public @interface JsonAlias

フィールド、メソッド、パラメータなどに適用でき、複数の別名を配列形式で渡すことができます。

コード例

以下の例では、EmployeeクラスとTechnologyクラスの各フィールドに@JsonAliasを付与し、デシリアライズ時に複数の名前を受け入れられるようにしています。

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import java.io.*;

public class ObjectToJsonTest {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        Technology tech = new Technology("Java", "Oracle");
        Employee emp = new Employee(110, "Raja", tech);
        String jsonWriter = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(emp);
        System.out.println(jsonWriter);
    }
}

// Technologyクラス
class Technology {
    @JsonProperty("skill")
    private String skill;
    @JsonProperty("subSkill")
    @JsonAlias({"sSkill", "mySubSkill"})
    private String subSkill;

    public Technology(){}
    public Technology(String skill, String subSkill) {
        this.skill = skill;
        this.subSkill = subSkill;
    }
    public String getSkill() {
        return skill;
    }
    public void setSkill(String skill) {
        this.skill = skill;
    }
    public String getSubSkill() {
        return subSkill;
    }
    public void setSubSkill(String subSkill) {
        this.subSkill = subSkill;
    }
}

// Employeeクラス
class Employee {
    @JsonProperty("empId")
    private Integer id;
    @JsonProperty("empName")
    @JsonAlias({"ename", "myename"})
    private String name;
    @JsonProperty("empTechnology")
    private Technology tech;

    public Employee(){}
    public Employee(Integer id, String name, Technology tech){
        this.id = id;
        this.name = name;
        this.tech = tech;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Technology getTechnology() {
        return tech;
    }
    public void setTechnology(Technology tech) {
        this.tech = tech;
    }
}

コードのポイント

  • subSkillフィールドには「sSkill」「mySubSkill」という2つの別名が定義されています。
  • nameフィールドには「ename」「myename」という2つの別名が定義されています。
  • そのため、入力JSONで"empName""ename""myename"のいずれかが使われていても、すべて正しくnameフィールドにマッピングされます。

出力結果

上記プログラムを実行すると、シリアライズ時には別名ではなく、@JsonPropertyで指定した正式なプロパティ名のみが出力されます。

{
  "technology" : {
    "skill" : "Java",
    "subSkill" : "Oracle"
  },
  "empId" : 110,
  "empName" : "Raja",
  "empTechnology" : {
    "skill" : "Java",
    "subSkill" : "Oracle"
  }
}

まとめ

@JsonAliasは、外部APIなど異なる命名規則を持つJSONデータを柔軟に受け入れたい場合に非常に便利なアノテーションです。デシリアライズ時のみ有効であり、出力されるJSONには影響しないため、入力と出力で命名を分けたいケースにも最適です。

  1. JavaのJacksonでJSONのフィールド名を変更する方法:@JsonPropertyアノテーションの使い方

    @JsonPropertyアノテーションとはJavaでJSONを扱う際に広く使われているライブラリ「Jackson」には、@JsonPropertyというアノテーションが用意されています。このアノテーションは、JSONのシリアライズ(Javaオブジェクト→JSON)やデシリアライズ(JSON→Javaオブジェクト)の処理において、プロパティやメソッドに対して指定することができます。@JsonPropertyには、オプションの「name」パラメータを渡すことができます。これは、Javaクラスのプロパティ名と、JSON側のキー名が異なる場合に非常に便利です。キー名とプロパティ名が一致している場合:

  2. 【Java】GsonライブラリでnullフィールドをJSONにシリアライズする方法

    デフォルト設定では、Gsonはnull値を持つフィールドをJSONにシリアライズしません。Javaオブジェクト内のフィールドがnullである場合、そのフィールドは出力から除外されます。しかし、GsonBuilderクラスを利用することで、null値も強制的にシリアライズさせることが可能です。具体的には、Gsonオブジェクトを生成する前に、GsonBuilderインスタンスに対してserializeNulls()メソッドを呼び出します。このメソッドを呼び出した後に作成されたGsonインスタンスは、シリアライズ結果のJSONにnullフィールドを含めるようになります。構文public GsonBu