Java 如何最好地在XML中实现HATEOAS的链接关系?

Java 如何最好地在XML中实现HATEOAS的链接关系?,java,web-services,rest,jaxb,domain-driven-design,Java,Web Services,Rest,Jaxb,Domain Driven Design,我们有一个Java服务器web应用程序,其中系统的核心包含一个非常复杂的域模型,该模型是根据域驱动设计的原则设计的。在大多数情况下,这些域对象很少受到应用程序和其他关注点的影响 我们现在希望在系统前面放一个REST web服务API,我正在努力解决如何最好地实现我们自己的新媒体类型中的HATEOAS链接。例如,假设我们有一个域类foo,它具有带有JAX-B注释的id和名称属性: @XmlType(name = "foo") public class FooImpl implements Foo

我们有一个Java服务器web应用程序,其中系统的核心包含一个非常复杂的域模型,该模型是根据域驱动设计的原则设计的。在大多数情况下,这些域对象很少受到应用程序和其他关注点的影响

我们现在希望在系统前面放一个REST web服务API,我正在努力解决如何最好地实现我们自己的新媒体类型中的HATEOAS链接。例如,假设我们有一个域类
foo
,它具有带有JAX-B注释的id和名称属性:

@XmlType(name = "foo")
public class FooImpl implements Foo {

    private String name;
    private String id;

    ...snip....

@XmlID
@XmlAttribute
@Override
public String getId() {
    return id;
}

    @XmlElement
    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(final String name) {
        this.name = name;
    }
}
但我要返回的XML如下所示:

<foo id="123" href="http://myserver.com/foos/123">
   <name>myFoo</name>
   <links>
          <link rel="previous" href="http://myserver.com/foos/122" type="application/mything+xml" />
          <link rel="next" href="http://myserver.com/foos/124" type="application/mything+xml" />
          <link rel="edit" href="http://myserver.com/foos/123" type="application/mything+xml" />
          <link rel="revise" href="http://myserver.com/foos/123" method="put" type="application/mything+xml" />
          <link rel="cancel" href="http://myserver.com/foos/123?op="cancel"" method="post" type="application/mything+xml" />
   </links>
</foo>

美孚
做这件事的最佳方法是什么,这样我就不会因为这些媒体类型的链接而污染我的域设计,但仍然可以使用JAX-B的强大功能进行XML编组?以下是一些想法:

1) JAX-B适配器-我可以用它们修改实体的XML并插入链接吗..可能吗?这合理吗?有什么例子吗

2) DTO层-创建一个新的REST服务层,用于转换DTO中的域对象。到目前为止,我们能够避免DTO带来的麻烦。虽然这将为我们返回给客户机的内容提供完全的灵活性,但我也不希望在这里创建领域不可知的客户机

3) 链接标题-我非常喜欢这个想法,但我认为它(本身)不起作用,因为有时我们的资源包含子资源的集合。在这种情况下,子资源仍然必须编组为包含链接/HREF等的XML。因此,虽然链接头解决了顶级类型的问题,但它并不能解决整个问题。别客气


有没有另一种方法可以帮助我避免DTO,同时对域模型保持透明?

问题是,正确生成链接需要知道生成链接的上下文,这反过来意味着简单的JAXB拦截器无法完成这项工作:它们根本不知道插入什么URL。此外,生成下一个和上一个链接需要知道这些值是什么;说它们是连续的可能不太安全,因为这意味着当其他资源被删除时,一个资源会更改其URL,这将是疯狂的


最安全、最简单的方法是一个包装器类(上面有JAXB序列化注释),它将委托给DAO层以获取所需的信息。虽然这可能需要编写相当多的代码,但至少很容易获得正确的代码。奇特的自动装饰将更加困难。

RESTEasy支持通过atom或标题链接的链接。有一些额外的注释,您可以通过这些注释来指向链接的服务。请参阅RESTEasy文档的第8章。

向模型添加链接需要扩展域类,但DAO层无法实例化此类对象。考虑聚合并将JAXB(或任何XML映射)添加到该层。如果我理解,创建一个REST模型,该模型将域对象与链接聚合并发送过来。有点像DTO,但更像是扩展域以包含链接。我明白了吗?是的,我会制作包装。如有必要,将调用委派给DAO对象。基本上就是这样。@HDave,你解决了这个问题吗?如果是这样,你介意发布一些代码吗?我希望做类似的事情。@craig-我现在正在做。我试图解决如何为同一个域对象配置多个不同的媒体类型表示的问题。我一有答案就会贴出来!