Java中的WADL:温和的介绍

WADL( Web应用程序描述语言 )对REST而言,WSDL对SOAP而言。 这种语言的仅仅存在引起了很多争议(请参阅: 我们需要WADL吗? 或者 需要 WADL还是不需要WADL )。 我可以想到使用WADL的一些合法用例,但是如果您已经在这里,则可能不打算再进行讨论。 因此,让我们继续前进到WADL本身。

原则上,WADL与WSDL类似,但是语言的结构有很大不同。 虽然WSDL定义了使用或产生其中一些消息和操作的平面列表,但WADL强调了RESTful Web服务的分层性质。 在REST中,主要工件是资源。 每个资源(名词)都表示为URI。 每个资源都可以定义CRUD操作(动词,作为HTTP方法实现)和嵌套资源。 嵌套资源与父资源有很强的关系,通常代表所有权。

一个简单的示例是表示书籍列表的http://example.com/api/books资源。 您可以(HTTP)获取此资源,这意味着检索整个列表。 您还可以获取http://example.com/api/books/7资源,以在books资源中获取第7本书的详细信息。 或者,您甚至可以使用相同的URI放置新版本或完全删除资源。 您不仅仅局限于一个嵌套级别:获取http://example.com/api/books/7/reviews?page=2&size=10将会检索第二本书(最多10本书)的第二页(最多10个条目)。 显然,您也可以在书籍旁边放置其他资源,例如http://example.com/api/readers

就像WSDL人员能够做到的那样,要求正式而精确地描述每个可用资源,方法,请求和响应。 WADL是描述“可用URI”的选项之一,尽管有些人认为编写良好的REST服务应该是自描述性的(请参阅HATEOAS )。 但是,这是一个简单的空WADL文档:

<application xmlns="http://wadl.dev.java.net/2009/02">
    <resources base="http://example.com/api"/>
</application>

这里没什么好看的。 请注意, <resources>标记定义了基本API地址。 我们将要添加的所有命名资源都相对于该地址。 您还可以定义几个<resources>标记来描述多个API。 因此,让我们添加一个简单的资源:

<application xmlns="http://wadl.dev.java.net/2009/02">
    <resources base="http://example.com/api">
        <resource path="books">
            <method name="GET"/>
            <method name="POST"/>
        </resource>
    </resources>
</application>

这使用两种可能的方法在http://example.com/api/books下定义资源:GET用于检索整个列表,而POST用于创建(添加)新项目。 根据您的要求,您可能还希望允许DELETE方法(删除所有项目),并且WADL负责记录允许的内容。

还记得我们开头的示例: / books / 7吗? 显然7只是一个示例,我们不会在WADL中声明所有可能的书ID。 而是有一个方便的占位符语法:

<application xmlns="http://wadl.dev.java.net/2009/02">
    <resources base="http://example.com/api">
        <resource path="books">
            <method name="GET"/>
            <resource path="{bookId}">
                <param required="true" style="template" name="bookId"/>
                <method name="GET"/>
            </resource>
        </resource>
    </resources>
</application>

您应注意两个重要方面:首先,使用{ bookId }占位符代替嵌套资源。 其次,为了清楚起见,我们正在使用< param />标记记录此占位符。 我们很快将看到如何将其与方法结合使用。 为了确保您仍然与我在一起,上面的文档介绍了GET / booksGET / books / some_id资源。

<application xmlns="http://wadl.dev.java.net/2009/02">
    <resources base="http://example.com/api">
        <resource path="books">
            <method name="GET"/>
            <resource path="{bookId}">
                <param required="true" style="template" name="bookId"/>
                <method name="GET"/>
                <method name="DELETE"/>
                <resource path="reviews">
                    <method name="GET">
                        <request>
                            <param name="page" required="false" default="1" style="query"/>
                            <param name="size" required="false" default="20" style="query"/>
                        </request>
                    </method>
                </resource>
            </resource>
        </resource>
        <resource path="readers">
            <method name="GET"/>
        </resource>
    </resources>
</application>

Web服务变得越来越复杂,但是它描述了很多操作。 首先, GET / books / 42 / reviews是有效的操作。 但是有趣的部分是嵌套的<request />标记。 如您所见,我们可以独立描述每种方法的参数。 在我们的案例中,定义了可选的查询参数(与之前用于URI占位符的模板参数相反)。 这为客户端提供了有关可接受的页面和大小查询参数的其他知识。 这意味着/ books / 7 / reviews?page = 2&size = 10是有效的资源标识符。 我是否提到过每个资源,方法和参数都可以按照WADL规范附加文档?

我们将在这里停止,仅提及WADL的其余部分。 首先,到目前为止,您可能已经猜到了,每个<method />都有一个<response />子标记。 请求和响应都可以定义请求或响应必须遵循的确切语法(例如,在XML Schema中)。 该响应还可以记录可能的HTTP响应代码。 但是,由于我们将使用到目前为止在代码优先应用程序中获得的知识,因此我特意留下了<grammars />定义。 WADL是敏捷的,它使您可以定义所需的尽可能少的信息。

因此,我们知道了WADL的基础知识,现在我们想使用它,可以作为基于Java的应用程序的使用者或生产者。 幸运的是,该语言本身有一个wadl.xsd XML Schema描述,我们可以使用它来生成可使用JAXB注释的POJO(使用JDK中的xjc工具):

$ wget http://www.w3.org/Submission/wadl/wadl.xsd
$ xjc wadl.xsd

在那里...挂了! 软件开发人员的生活充满挑战和非凡的问题。 有时,这只是一个令人讨厌的网络过滤器,可疑数据包(连同您半个小时的生命)消失了。 一旦您回想起2008年左右写的文章: W3C的DTD流量过大 ,就不难发现问题了

<xs:import namespace="http://www.w3.org/XML/1998/namespace"
  schemaLocation="http://www.w3.org/2001/xml.xsd"/>

从浏览器访问xml.xsd会立即返回HTML页面,但是xjc工具将永远等待。 在本地下载此文件并更正wadl.xsd中schemaLocation属性有助于。 总是小事……

$ xjc wadl.xsd 
parsing a schema... 
compiling a schema... 
net/java/dev/wadl/_2009/_02/Application.java 
net/java/dev/wadl/_2009/_02/Doc.java 
net/java/dev/wadl/_2009/_02/Grammars.java 
net/java/dev/wadl/_2009/_02/HTTPMethods.java 
net/java/dev/wadl/_2009/_02/Include.java 
net/java/dev/wadl/_2009/_02/Link.java 
net/java/dev/wadl/_2009/_02/Method.java 
net/java/dev/wadl/_2009/_02/ObjectFactory.java 
net/java/dev/wadl/_2009/_02/Option.java 
net/java/dev/wadl/_2009/_02/Param.java 
net/java/dev/wadl/_2009/_02/ParamStyle.java 
net/java/dev/wadl/_2009/_02/Representation.java 
net/java/dev/wadl/_2009/_02/Request.java 
net/java/dev/wadl/_2009/_02/Resource.java 
net/java/dev/wadl/_2009/_02/ResourceType.java 
net/java/dev/wadl/_2009/_02/Resources.java 
net/java/dev/wadl/_2009/_02/Response.java 
net/java/dev/wadl/_2009/_02/package-info.java

由于我们将在基于Maven的项目中使用这些类(并且我讨厌将生成的类提交到源存储库),因此让我们将xjc执行移至maven生命周期:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>
    <version>1.3</version>
    <dependencies>
        <dependency>
            <groupId>net.java.dev.jaxb2-commons</groupId>
            <artifactId>jaxb-fluent-api</artifactId>
            <version>2.0.1</version>
            <exclusions>
                <exclusion>
                    <groupId>com.sun.xml</groupId>
                    <artifactId>jaxb-xjc</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <goals>
                <goal>xjc</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <arguments>-Xfluent-api</arguments>
        <bindingFiles>bindings.xjb</bindingFiles>
        <packageName>net.java.dev.wadl</packageName>
    </configuration>
</plugin>

嗯, pom.xml并不是有史以来最简洁的格式……没关系,在每次编译之前,这都会在编译源代码之前生成WADL XML类。 我还喜欢通顺-API插件, 与*()与普通制定者一起的方法增加了回允许链接。 很方便 最后,我们为生成的工件定义更合适的包名称(如果您发现net.java.dev.wadl._2009._02足够好的包名称,则可以跳过此步骤),并将Wadl前缀添加到所有生成的类bindings.xjb文件中:

<jxb:bindings version="1.0"
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  jxb:extensionBindingPrefixes="xjc">
 
    <jxb:bindings schemaLocation="../xsd/wadl.xsd" node="/xs:schema">
        <jxb:schemaBindings>
            <jxb:nameXmlTransform>
                <jxb:typeName prefix="Wadl"/>
                <jxb:anonymousTypeName prefix="Wadl"/>
                <jxb:elementName prefix="Wadl"/>
            </jxb:nameXmlTransform>
        </jxb:schemaBindings>
    </jxb:bindings>
 
</jxb:bindings>

现在,我们准备使用JAXB和POJO类以XML格式生成和使用WADL。 有了这些知识和基础,我们就可以开发一些有趣的库了,这将是下一篇文章的主题。

参考: Java和社区博客上我们的JCG合作伙伴 Tomasz Nurkiewicz 对WADL(Java)的简要介绍。


翻译自: https://www.javacodegeeks.com/2012/01/wadl-in-java-gentle-introduction.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值