私は、多数のクライアントにバックエンド機能を提供する Java EE アプリケーションを担当しています。一部のクライアントも Java で記述されているため、サーバーとクライアントが共有する別の jar にエンティティを抽出しました。
サーバーは永続性のために JPA2 を使用し、クライアントとの通信には JAX-RS を使用し、XML および JSON との間のシリアル化には JAXB を使用します。その結果、(共有) クラス ファイルには、JPA アノテーションと JAXB アノテーションの両方が含まれます。
明らかに、同じオブジェクトがサーバー (マネージド JPA エンティティ) とクライアント (デシリアライズされた POJO) では動作が異なります (特に 1 対多の関係に関して)。
質問:個々のメソッド呼び出しが実行される場所に応じて異なる動作をさせたい場合があります。同じクラスの 2 つの実装を手動で維持する必要がないように、継承によってこれを解決できますか?
例:
- チームには多くのプレーヤーがいます。選手には名前があります。
GET /team/<id>
リクエストは、チームを取得するため、およびチームGET /team/<id>/<playerName>
の特定のプレーヤーを取得するためにマップされます。- マーシャリングとシリアライゼーションの場合、
Team
は「フラット」のままでなければなりません (プレーヤーを含めないでください)。ただし、シリアライゼーションに名前を含めて、取得できるプレーヤーをクライアントが詳細に把握できるようにします。
サーバー側では、次のように構築します。
@Entity
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Team {
/* some other fields, belonging to the Team */
@OneToMany(fetch = FetchType.LAZY, mappedBy="team")
@XmlTransient // don't marshall the players
List<Player> players;
/* getters and setters as necessary */
@XmlElement
public List<String> getPlayerNames() {
List<String> names = new ArrayList<String>();
for (Player p : getPlayers()) {
names.add(p.getName());
}
return names;
}
}
クライアント側では、次のようにマッピングします。
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Team {
/* some other fields, belonging to the Team */
List<String> playerNames;
public List<String> getPlayerNames() {
return playerNames;
}
public void setPlayerNames(List<String> playerNames) {
this.playerNames = playerNames;
}
/* getters and setters as necessary */
}
このようにして、プレイヤー名はサーバー側で( @XmlElement
-annotatedを介して) マーシャリングされます。getPlayerNames()
クライアントがそれを受け取ると、リストを適切にアンマーシャリングします。誰もが幸せです。
ただし、今では、2 つの本質的に同一のクラスを維持する必要がありますが、わずかな違いしかありません...これを適切に行うための最良の方法は何ですか?