我负责为多个客户端提供后端功能的Java EE应用程序。有些客户端也是用Java编写的,所以我已经将我的实体抽取到单独的jar中,该服务器和客户端共享。Java EE:在服务器和客户端之间共享实体类
服务器使用JPA2为持久性,JAX-RS用于与客户和JAXB通信进行序列化到/从XML和JSON。因此,(共享)类文件包含JPA和JAXB注释。
显然,同一个对象在服务器(它是一个托管JPA实体)和客户端(它是一个反序列化的POJO)的行为不同 - 特别是关于一对多关系。
问题:有时我希望单个方法调用的行为有所不同,具体取决于它们的执行位置。我可以通过继承来解决这个问题吗,这样我就不必手动维护同一类的两个实现了吗?
例子:
- 一支球队有很多球员。一名球员有一个名字。
- 请求都被映射到
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 */
}
这样,playernames在服务器端编组(通过@XmlElement
-annotated getPlayerNames()
)。当客户收到它时,它会正确解组清单。每个人都很高兴。
不过,现在我必须维护两个基本相同的类,其中只有细微的差别出现...什么是正确做到这一点的最好方法是什么?
谢谢。当然,实体是分离的,交换只是JAX-RS的本质。因为这些实体*已经是DTO了。而且,是的,在少数情况下,同一个类在客户端和服务器上的行为不同 - 我的问题的核心是如何更好地组织类。你能提供一个建议吗? – Hank
我的答案的第一段是指出我反对使用实体作为DTO。我会使用单独的类。但是,如果我不够清楚,那只是一个附注。关于类的组织,如果你想在客户端和服务器上共享一些常见的行为:在包A中创建一个基类,将其扩展到服务器的A.S包和客户端的A.C。然后在服务器的相同JAR中捆绑A + A.S,为客户端捆绑A + A.C。 Maven多模块项目(一个模块用于A,一个模块用于A.C,A作为依赖项,一个用于A.S,依赖于A)可能有所帮助。 – aha
感谢@aha为Maven多模块项目的想法...这是我一直在寻找几个星期的关键词。 –