JavaのJacksonで@JsonManagedReferenceと@JsonBackReferenceを使いこなす方法
@JsonManagedReferenceと@JsonBackReferenceアノテーションは、親子関係のような双方向の参照を持つJavaオブジェクトをJSON構造として扱うために使用されます。これらのアノテーションを適切に組み合わせることで、循環参照による無限ループ(StackOverflowError)を回避しながら、安全にシリアライズを行うことができます。
それぞれの役割は以下の通りです。
- @JsonManagedReference:前方参照(フォワードリファレンス)を表し、シリアライズ(Javaオブジェクト → JSON)の過程で含められます。
- @JsonBackReference:逆参照(バックリファレンス)を表し、シリアライズの過程で省略されます。デシリアライズ(JSON → Javaオブジェクト)の際には、両者の関連付けが自動的に復元されます。
以下の例では、@JsonManagedReferenceと@JsonBackReferenceアノテーションの実際の実装方法を示します。
コード例
import java.util.*;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
public class ManagedReferenceBackReferenceTest {
public static void main(String args[]) throws JsonProcessingException {
BackReferenceBeanTest testBean = new BackReferenceBeanTest(110, "Sai Chaitanya");
ManagedReferenceBeanTest bean = new ManagedReferenceBeanTest(135, "Adithya Ram", testBean);
testBean.addEmployees(bean);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
System.out.println(jsonString);
}
}
class ManagedReferenceBeanTest {
public int empId = 115;
public String empName = "Raja Ramesh";
@JsonManagedReference
public BackReferenceBeanTest manager;
public ManagedReferenceBeanTest(int empId, String empName, BackReferenceBeanTest manager) {
this.empId = empId;
this.empName = empName;
this.manager = manager;
}
}
class BackReferenceBeanTest {
public int empId = 125;
public String empName = "Jai Dev";
@JsonBackReference
public List<ManagedReferenceBeanTest> list;
public BackReferenceBeanTest(int empId, String empName) {
this.empId = empId;
this.empName = empName;
list = new ArrayList<ManagedReferenceBeanTest>();
}
public void addEmployees(ManagedReferenceBeanTest managedReferenceBeanTest) {
list.add(managedReferenceBeanTest);
}
}
出力結果
{
"empId" : 135,
"empName" : "Adithya Ram",
"manager" : {
"empId" : 110,
"empName" : "Sai Chaitanya"
}
}
出力結果を見ると、@JsonManagedReferenceを付けたフィールド(manager)はJSONに正常に出力されている一方で、@JsonBackReferenceを付けたフィールド(list)は出力から除外されていることがわかります。この仕組みにより、親子間で互いを参照し合うオブジェクトグラフでも、無限ループを発生させることなくJSONへの変換が可能になります。
-
Javaの抽象クラスとインターフェース、どちらを使うべき?使い分けのポイントを徹底解説
Javaプログラミングにおいて、「抽象クラス」と「インターフェース」はどちらもオブジェクト指向設計に欠かせない要素ですが、それぞれ役割が異なります。インターフェースは契約(コントラクト)として振る舞いを定義し、システム間のやり取りの取り決めとしても機能します。一方、抽象クラスは主にサブクラスに対してデフォルトの動作を定義するために使われ、すべての子クラスが共通の機能を持つことを保証します。 抽象クラスを使うべきケース 継承を活用する場合: 抽象クラスは派生クラスに対して共通の基底クラス実装を提供できるため、継承の概念を利用する設計に適しています。 非公開メンバーを宣言したい場合: インターフ
-
Javaの抽象クラスと抽象メソッドの基本と実装例
はい、Javaでは抽象クラスや抽象メソッドを簡単に作成することができます。本記事では、abstractキーワードを使った抽象クラスの定義方法と、その基本的な構造について具体例を交えて解説します。抽象クラスとは抽象クラス(abstract class)は、その名の通り「抽象的」な概念を表すためのクラスで、直接インスタンス化することはできません。共通の属性や振る舞いをサブクラスに継承させるための設計図として活用されます。抽象クラスを作成する方法は非常にシンプルで、クラス宣言時に class キーワードの前に abstract キーワードを付けるだけです。コード例/* ファイル名 : Employe