2012-01-16 48 views
5

我们有一个Java服务器Web应用程序,其中系统的核心包含一个非常复杂的领域模型,它是根据领域驱动设计的原则设计的。在大多数情况下,这些领域对象对其他关注的应用程序影响很小。如何最好地在XML中为HATEOAS实现链接关系?

我们现在正在考虑在系统前放置一个REST Web服务API,并且我正在努力如何最好地实现我们自己的新媒体类型中的HATEOAS链接。例如,让我们说,我们有与JAX-B上的注释的ID和name属性域类foo

@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)Link Headers - 我真的很喜欢这个想法,但我认为它不会工作(本身),因为我们的资源有时包含子资源的集合。在这种情况下,子资源仍然必须编组为XML,其中包含链接/ hrefs等。因此,链接标题将问题解决为顶级类型时,它不能解决整个问题。随意否则!

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

+0

向模型添加链接需要扩展你的域类,但是你的DAO层不能实例化这些对象。考虑聚合并将JAXB(或任何XML映射)添加到该层。 – 2012-01-16 20:17:00

+0

如果我明白,创建一个REST模型,将链接聚合到域对象并发送。有点像DTO,但更像是扩展域以包含链接。我明白吗? – HDave 2012-01-17 03:44:45

+2

是的,我会创建包装。如有必要,将调用委托给DAO对象。所以基本上这是[装饰设计模式](http://en.wikipedia.org/wiki/Decorator_pattern)。 – 2012-01-17 17:59:17

回答

2

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

最安全,最简单的方法将成为一个包装类(包含JAXB序列化注释),它委托给DAO层以获取所需信息。虽然这可以写相当数量的代码,但至少可以很容易地得到这样的代码。花式自动装饰将会更加困难。

0

RESTEasy通过原子或标题链接支持链接。有一些额外的注释可以用来指出链接的服务。请参阅RESTEasy文档的第8章。