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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

类成员函数模板特化

//类成员函数模板特化 #include <stdio.h> class A{ public:template <class T>void Print(){printf("A template\n");} };template<> void A::Print<int>(){printf("int\n"); }int main(){A a;a.Print<double>();a.Print&l…

为云量身定制您的服务

相信大家都听说过Amazon的AWS。作为业内最为成熟的云服务提供商&#xff0c;其运行规模&#xff0c;稳定性&#xff0c;安全性都已经经过了市场的考验。时至今日&#xff0c;越来越多的应用被部署在了AWS之上。这其中不乏Zynga及Netflix这样著名的服务。 然而这一切并没有停滞不…

在Vaadin和JSF之间选择

随着最新版本的Primefaces 3.0的发布&#xff0c;JSF终于达到了前所未有的成熟度和实用性&#xff0c;使其与其他流行的Rich Internet Applications&#xff08;RIA&#xff09;选项如Google Web Toolkit&#xff08;GWT&#xff09;&#xff0c;ExtJS&#xff0c;Vaadin&#…

20145202马超《信息安全系统设计基础》实验二总结

[实验二]&#xff08;http://www.cnblogs.com/nizaikanwoma/p/6131778.html&#xff09; 转载于:https://www.cnblogs.com/tuolemi/p/6131987.html

java 连接ldap_ldap java 连接demo

public class LDAPHelper {/*** LDAP可以理解为一个多级目录&#xff0c;这里&#xff0c;表示要连接到那个具体的目录*/private final String baseDn "ouPeople,dcchangyeyi,dccom";private LdapContext ctx null;private final Control[] connCtls null;private…

flask开发restful api系列(1)

在此之前&#xff0c;向大家说明的是&#xff0c;我们整个框架用的是flask sqlalchemy redis。如果没有开发过web&#xff0c;还是先去学习一下&#xff0c;这边只是介绍如果从开发web转换到开发移动端。如果flask还不是很熟悉&#xff0c;我建议先到这个网站简单学习一下&am…

Apache Commons Lang StringUtils

因此&#xff0c;认为最好谈论我喜欢的另一个Java库。 它已经存在了一段时间&#xff0c;也许不是最令人兴奋的库&#xff0c;但是它非常有用。 我可能每天都使用它。 org.apache.commons.lang.StringUtils StringUtils是Apache Commons Lang&#xff08; http://commons.apac…

JEE7:展望新时代

计划于2012年下半年发布的Java EE 7预计的JSR都已启动并正在运行。 Java EE 7发行版是日期驱动的&#xff0c;它将反映该行业迁移到云中时不断变化的需求&#xff1a;任何未准备就绪的内容将推迟到Java EE 8中使用 。 这是Java EE 7平台中不同规范的关键功能的更新和摘要。 1。…

Cocos2d-JS项目之UI界面的优化

测试环境&#xff1a; iphone4、iOS6.1.2、chrome 37.2062.60&#xff0c;Cocos2d-js 3.6 之前写了不少&#xff0c;实际项目也按这个去优化了&#xff0c;也有效果&#xff0c;但到最后才发现&#xff0c;尼玛&#xff0c;之前都搞错了&#xff0c;之所以有效果是歪打正着。。…

java数_java大数

java大数还是很好用的&#xff01;基本加入&#xff1a;import java.math.BigInteger;import jave.math.BigDecimal;分别是大数和大浮点数。首先读入可以用&#xff1a;Scanner input new Scanner(System.in);BigInteger a input.nextBigInteger();这样读还是很方便的当然还有…

【Qt之Quick模块】6. QML语法详解_2类型系统

描述 在QML文档中对象层次结构的定义中可能使用的类型可以来自各种来源。它们可能是: 由QML语言原生提供通过QML模块通过c注册由QML模块作为QML文档提供 此外&#xff0c;应用程序开发人员可以通过直接注册c类型&#xff0c;或者通过在QML文档中定义可重用的组件(然后可以导…

JS显示当前时间(包含农历时间)

时间格式&#xff1a; JavaScript代码&#xff1a; var sWeek new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");var dNow new Date();var CalendarData new Arra…

Maven原型创建技巧

我最近需要为姜黄SOA项目创建一些Maven原型。 对于不了解的人来说&#xff0c; Maven原型是一种基于一些预先罐装的项目模板生成项目的方法。 对于当前的姜黄SOA原型&#xff0c;它将创建一个多模块Maven项目&#xff0c;该项目包含Interface和Service项目以及基本的WSDL和适当…

MyBatis操作指南-与Spring集成(基于注解)

转载于:https://www.cnblogs.com/weilu2/p/mybatis_spring_integration_basic_on_annotation.html

Windows mysql boost_Win7下Boost库的安装

Boost库是C领域公认的经过千锤百炼的知名C类库&#xff0c;涉及编程中的方方面面&#xff0c;简单记录一下使用时的安装过程1.boost库的下载boost库官网主页&#xff1a;www.boost.org2.安装将下载的压缩包解压到指定的目录3.建立编译工具bjam.exe在源码目录下执行bootstrap.ba…

5.2与终端进行对话

Linux提供了一个特殊的设备 /dev/tty &#xff0c;该设备始终是指向当前终端或者当前的登录会话。 FILE* output fopen("/dev/tty", "w"); //向终端写入字符串 fprintf(output, "%s\n", "world"); FILE* input fopen("/dev/tty…

JVM:如何分析线程转储

本文将教您如何分析JVM线程转储&#xff0c;并查明问题的根本原因。 从我的角度来看&#xff0c;线程转储分析是掌握Java EE生产支持的任何个人最重要的技能。 您可以从线程转储快照中获取的信息量通常远远超出您的想象。 我的目标是与您分享我在过去10年中积累的有关线程转储分…

极光推送JPush的快速集成

首先到极光推送的官网上创建一个应用&#xff0c;填写对应的应用名和包名。 创建好之后下载Demo 提取Sdk里面的图片和xml等资源文件放自己项目的相应位置&#xff0c;然后要注意的是.so文件的放置位置&#xff1a; 在main目录下新建一个jniLibs文件夹&#xff0c;放在这个文件夹…

c遗传算法的终止条件一般_Matlab2 :Matlab遗传算法(GA)优4~-r-具箱是基于基本操作 联合开发网 - pudn.com...

Matlab2所属分类&#xff1a;matlab例程开发工具&#xff1a;PDF文件大小&#xff1a;115KB下载次数&#xff1a;76上传日期&#xff1a;2007-09-07 20:04:29上 传 者&#xff1a;钱广说明&#xff1a; &#xff1a;Matlab遗传算法(GA)优4~-r-具箱是基于基本操作及终止条件、二…

用程序输出表格

做应用程序的时候经常需要输出excel表格&#xff0c;除了不同语言接口完善程度不同的麻烦以及要添加各种外部引用的麻烦之外还要考虑应用环境不同的office版本的问题&#xff0c;实在麻烦 当只需要输出数据&#xff0c;不管颜色什么的的话&#xff0c;有个避免上述麻烦的办法就…