我正在使用Java和JBoss7与RESTEasy。我创建了我的RESTful服务和客户端来测试我的服务:
ClientRequest request = new ClientRequest(
"http://localhost:8080/test/rest/cars");
request.accept(MediaType.APPLICATION_XML);
String input = "<car><carId>10.99</carId><carName>Ford</carName></car>";
request.body(MediaType.APPLICATION_XML, input);
ClientResponse<String> response = request.post(String.class);
System.out.println("Output from Server .... \n");
System.out.println(response.getStatus());
这完美无缺!这里唯一的问题是在客户端。我必须像String input = "<car><carId>10.99</carId><carName>Ford</carName></car>";
中那样发送硬编码的XML,因为客户端没有我拥有的对象。
客户端将模仿从get方法接收的XML表示,这对于大型复杂资源来说可能很难。
有没有办法让客户端知道他们想要发送的对象的正确结构,还是他们必须发送类型化的XML?
我可以给客户端类似于WSDL或XSD的东西,或者是否会违反REST的限制?
我见过人们会使用Xsteam和解组的解决方案,但他们认为客户端具有资源的类表示。
答案 0 :(得分:1)
不要在客户端代码中对XML消息进行硬编码。 XML是服务和客户端之间传递的东西。
让我们假设您将相同的服务暴露在不同的位置,而另一个只能理解XML格式,而另一个只能理解JSON。如果您要将您的客户端与硬编码消息一起使用,您将只能调用会话XML的服务。记住REST是关于资源的表示。
因为客户端没有我拥有的对象。客户端将模仿他从get方法收到的XML表示,这对于大型复杂资源来说很难做到。
有没有办法让客户端知道他们想要发送的对象的正确结构,还是他们必须发送类型化的XML?
请考虑您的客户端是一个通常与对象一起使用的Java应用程序。对象代表资源(例如car
),这是您的客户在内部使用的内容。
当需要调用服务时,您只需将这些对象编组为XML。当服务响应时,您将XML解组为对象。
根据使用的Accept
和Content-Type
标题,只需选择合适的marshaller / unmarshaller即可。然后,您甚至可以将某些内容作为XML发送并以JSON形式接收。
当然,RESTeasy clients可以使用与服务端相同的注释,甚至可以在服务和客户端之间重用某些Java类型(类),但这些Java类在客户端变得无用用其他技术编写:C#,Python,C ++等。
客户为什么要关心服务使用的类型?它应该只关心表示。在内部,客户端可以使用它想要的任何类型(独立于服务),并且只有在与服务通信时才与正确的表示进行通信。
我可以给客户端类似于WSDL或xsd的东西,或者是否会违反REST的约束?
这有点棘手。
REST是用于构建分布式系统的软件架构风格。不幸的是,不同的人对这种“风格”的理解不同,因此有很多所谓的RESTful API,它们只是简单地描述了使用哪些方法,在哪些URL以及将要发送回来的“类型”。
正如Roy T. Fielding自己所强调的那样,这是做错的REST方式:REST APIs must be hypertext-driven。
RESTful客户端不需要事先了解要访问的URL或用于通信的“类型”。理解交换中使用的媒体类型就是它所需要的(我不是在谈论application/xml
,它只是说明了没有语义或内部描述的消息格式。
结果为什么服务应该提供WSDL?实际上(虽然WSDL 2.0可以描述RESTful服务),实际上我们正在谈论WADL。但REST社区实际上并没有考虑到WADL,所以这也是is a matter of "style"。
如果您正在“通过本书”进行REST,则不需要WADL。如果你实际上只有一个基于HTTP的界面,我认为你可以提供一个WADL来减轻其他程序员在开发客户端时的生活。
我见过人们会使用Xsteam和解组的解决方案,但他们认为客户端具有资源的类表示。
RESTeasy支持JAXB编组,因此只需很少的工作即可。