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_ONLYやNONEと組み合わせて、必要な範囲だけを制御するのが安全な使い方です。
-
Javaのpack()メソッドとは?使い方とsetSize()との違いを解説
pack()メソッドは、JavaのWindowクラスで定義されているメソッドで、フレーム内のすべてのコンポーネントがそれぞれの推奨サイズ(preferred size)以上で表示されるように、ウィンドウのサイズを自動的に調整します。 代替手段として、setSize()メソッドやsetBounds()メソッドを呼び出して、フレームのサイズを明示的に指定する方法もあります。しかし一般的には、pack()メソッドを使用する方がsetSize()よりも推奨されています。その理由は、pack()がフレームのサイズ決定をレイアウトマネージャーに委ねることができ、レイアウトマネージャーはプラットフォーム間の
-
Pythonの%sと%rの違い:いつ%rを使うべきか?
Pythonの文字列フォーマットにおいて、%sはstr()を使ってオブジェクトを文字列化し、%rはrepr()を使って文字列化します。整数などの一部のオブジェクトでは、両者は同じ結果を返します。しかし、repr()には重要な特徴があります。対応している型については、有効なPython構文として評価できる文字列を返すという規約に従う点です。つまり、その出力を使えば、元のオブジェクトを曖昧さなく再現できるのです。例えば、改行文字を含む文字列の場合、%sでは実際に改行されて表示されるのに対し、%rではエスケープシーケンスの\nがそのまま表示され、引用符も保持されます。具体例>>>