原則上,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 / books和GET / 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