如果 JAX-RS 应用程序的方法将返回域对象,则表示(例如 JSON)将包含该对象的所有属性 - 对吗?但是如果这个对象包含不应该暴露给网络的“私人”数据呢?
从外到内的另一个方向是什么:如何防止私有字段被覆盖?
唯一的解决方案似乎是创建数据传输对象 (dto)。
除非无法指定要映射的字段,否则使用“自动映射器”不是解决方案。
那么,强制 JAX-RS 开发人员创建 DTO 吗?还是有其他解决方案?
如果 JAX-RS 应用程序的方法将返回域对象,则表示(例如 JSON)将包含该对象的所有属性 - 对吗?但是如果这个对象包含不应该暴露给网络的“私人”数据呢?
从外到内的另一个方向是什么:如何防止私有字段被覆盖?
唯一的解决方案似乎是创建数据传输对象 (dto)。
除非无法指定要映射的字段,否则使用“自动映射器”不是解决方案。
那么,强制 JAX-RS 开发人员创建 DTO 吗?还是有其他解决方案?
为了对实体的 XML 进行透明编组和解组,请使用 JAXB 注释对其进行注释(可以使用 JPA 和 JAXB 注释对类进行注释,这样,可以提供 XML 表示形式并保留在数据库中)。
@Entity
@XmlRootElement
public class MyEntity implements Serializable {
@Id @GeneratedValue
private Long id;
....
}
在上面的示例中,我只使用了一个 JAXB 注释@XmlRootElement
。现在,假设您不希望id
序列化 XML 中的属性。只需向其中添加 JAXB 注释@XmlTransient
:
@Entity
@XmlRootElement
public class MyEntity implements Serializable {
@XmlTransient
@Id @GeneratedValue
private Long id;
....
}
所以,不,对 DTO 没有严格的需求(以及将它们映射到实体和从实体映射出来的样板代码)。
我认为最好说 JAX-RS 要求您使用表示。
我的 Foo 域对象不知道它是以 RESTful 方式使用的。它只知道 Bar(另一个聚合根)以及它可以通过该 Bar 导航的任何实体。事实上,我也有这个应用程序的命令行界面,它不使用 REST 甚至 HTTP。
我的 RESTful 接口将 Foo/Bar 包装到通过 URI 相互链接的表示中。我想您可以调用这些 DTO,但是如果您(如其他答案中所述)只是用编组和解组它们所需的内容来注释您的域模型,那么我认为您正在将自己编码到一个禁止 HATEOAS 的角落。
当你有一个集合时,这一点也很明显。如果 Foo->*Bar 您是否要以未编组的形式返回所有 Bar 项目?为什么不只是一个 URI 和一些其他最小数据,例如
获取 foo/fff
<foo>
<link rel="self" uri="uri="foo/fff" />
<bar uri="bar/abc123">
<status="Active" />
</bar>
<bar uri="bar/qqq">
<status="Inactive" />
</bar>
</foo>
如果客户想了解更多关于给定 Bar 的信息,它可以
获取栏/abc123
<bar>
<link rel="self" uri="bar/abc123" />
<foo uri="foo/fff" />
<status>Active</status>
<title>Some Bar</title>
...
</bar>
@XmlTransient
(或相应的注释)指示映射器/编组器不要在序列化输出中包含带注释的属性。