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

Javaの@JsonAutoDetectアノテーションとは?使いどころと実装例を解説

@JsonAutoDetectアノテーションは、クラスレベルで指定することで、シリアライズ(直列化)およびデシリアライズ(復元)の際に、クラスのプロパティが検出される可視性(visibility)のルールを上書きできる機能です。Jacksonはデフォルトではgetterやsetterなどの公開メソッドを基準にJSONへの変換を行いますが、このアノテーションを使えば、privateフィールドなども強制的に対象に含めることができます。

可視性は以下のプロパティで個別に制御できます。

  • creatorVisibility:コンストラクタやファクトリメソッドの可視性
  • fieldVisibility:フィールドの可視性
  • getterVisibility:通常のgetterメソッドの可視性
  • setterVisibility:setterメソッドの可視性
  • isGetterVisibility:boolean型用のisGetterメソッドの可視性

また、JsonAutoDetectクラスには、Javaのアクセス修飾子の概念に対応したpublic staticな定数が定義されており、これらを組み合わせて細かく挙動を指定できます。主な定数は次のとおりです。

  • ANY:すべての可視性のメンバーを対象にする
  • DEFAULT:Jacksonのデフォルト設定に従う
  • NON_PRIVATE:private以外のメンバーを対象にする
  • NONE:該当種別のメンバーを一切自動検出しない
  • PROTECTED_AND_PRIVATE:protectedおよびprivateのみを対象にする
  • PUBLIC_ONLY:publicのメンバーのみを対象にする

コード例

以下の例では、getterを持たないStudentクラスに対して@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)を付与しています。これにより、privateフィールドもそのままJSONとして出力されます。

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

public class JsonAutoDetectTest {
    public static void main(String[] args) throws IOException {
        Address address = new Address("Madhapur", "Hyderabad", "Telangana");
        Name name = new Name("Raja", "Ramesh");
        Student student = new Student(address, name, true);

        ObjectMapper mapper = new ObjectMapper();
        String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(student);
        System.out.println("JSON: " + jsonString);
    }
}

// Addressクラス
class Address {
    private String firstLine;
    private String secondLine;
    private String thirdLine;

    public Address(String firstLine, String secondLine, String thirdLine) {
        this.firstLine = firstLine;
        this.secondLine = secondLine;
        this.thirdLine = thirdLine;
    }

    public String getFirstLine() {
        return firstLine;
    }

    public String getSecondLine() {
        return secondLine;
    }

    public String getThirdLine() {
        return thirdLine;
    }
}

// Nameクラス
class Name {
    private String firstName;
    private String secondName;

    public Name(String firstName, String secondName) {
        this.firstName = firstName;
        this.secondName = secondName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getSecondName() {
        return secondName;
    }
}

// Studentクラス
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
class Student {
    private Address address;
    private Name name;
    private Boolean isActive;

    public Student(Address address, Name name, Boolean isActive) {
        this.address = address;
        this.name = name;
        this.isActive = isActive;
    }
}

実行結果

{
  "address" : {
    "firstLine" : "Madhapur",
    "secondLine" : "Hyderabad",
    "thirdLine" : "Telangana"
  },
  "name" : {
    "firstName" : "Raja",
    "secondName" : "Ramesh"
  },
  "isActive" : true
}

まとめ

@JsonAutoDetectは、getter/setterを実装していないクラスや、DTOのようにフィールドを直接JSON化したい場合に特に便利です。一方で、privateフィールドまで無条件に公開すると意図しないデータが露出する可能性があるため、PUBLIC_ONLYNONEと組み合わせて、必要な範囲だけを制御するのが安全な使い方です。

  1. Javaのpack()メソッドとは?使い方とsetSize()との違いを解説

    pack()メソッドは、JavaのWindowクラスで定義されているメソッドで、フレーム内のすべてのコンポーネントがそれぞれの推奨サイズ(preferred size)以上で表示されるように、ウィンドウのサイズを自動的に調整します。 代替手段として、setSize()メソッドやsetBounds()メソッドを呼び出して、フレームのサイズを明示的に指定する方法もあります。しかし一般的には、pack()メソッドを使用する方がsetSize()よりも推奨されています。その理由は、pack()がフレームのサイズ決定をレイアウトマネージャーに委ねることができ、レイアウトマネージャーはプラットフォーム間の

  2. Pythonの%sと%rの違い:いつ%rを使うべきか?

    Pythonの文字列フォーマットにおいて、%sはstr()を使ってオブジェクトを文字列化し、%rはrepr()を使って文字列化します。整数などの一部のオブジェクトでは、両者は同じ結果を返します。しかし、repr()には重要な特徴があります。対応している型については、有効なPython構文として評価できる文字列を返すという規約に従う点です。つまり、その出力を使えば、元のオブジェクトを曖昧さなく再現できるのです。例えば、改行文字を含む文字列の場合、%sでは実際に改行されて表示されるのに対し、%rではエスケープシーケンスの\nがそのまま表示され、引用符も保持されます。具体例>>>