使用JSR 311及其实现,我们有一个强大的标准,可以通过Rest公开Java对象.但是在客户端方面似乎缺少可与Apache Axis for SOAP相媲美的东西 - 隐藏Web服务并将数据透明地封送回Java对象.
如何创建Java RESTful客户端?使用HTTPConnection和手动解析结果?或者专业客户,例如Jersey或Apache CXR?
这是一个老问题(2008)所以现在有比以往更多的选择:
Apache CXF有三种不同的REST客户端选项
泽西岛(如上所述).
Spring也有自己的名为RestTemplate
Commons HTTP Client为较旧的Java项目构建自己的.
更新大约2014年:
Sonatype的 Async-http-client.宁Async-http-client.
块上的新孩子提供NIO支持(虽然我不认为这真的会提高客户端的性能,就像服务器一样).
Apache HTTP组件(4.2)Fluent适配器 - 比旧的Commons HTTP Client 3更好,更易于用于构建自己的REST客户端.您将不得不使用像 Jackson这样的JSON解析支持,并且您可以使用 HTTP组件URIBuilder来构造类似于Jersey/JAX-RS Rest客户端的资源URI.HTTP组件也支持NIO,但我怀疑鉴于REST的短请求性质,您将获得比BIO更好的性能.
2016年更新:
OkHttp - 支持更新的HTTP协议(SPDY和HTTP2).适用于Android.不幸的是,它没有提供真正的基于反应器循环的异步选项(参见上面的Ning和HTTP组件).但是,如果您使用较新的HTTP2协议,这不是一个问题(假设连接计数有问题).
Retrofit - 将基于类似于某些Jersey和CXF扩展的接口存根自动创建客户端.使用OkHttp.
Apache HttpComponents 5应该具有HTTP2支持
关于选择HTTP/REST客户端的警告.确保检查您的框架堆栈用于HTTP客户端的内容,它如何进行线程化,并且如果它提供了一个,则理想情况下使用相同的客户端.也就是说,如果您使用Vert.x或Play之类的东西,您可能想尝试使用其支持客户端参与框架提供的任何总线或反应器循环......否则请为可能有趣的线程问题做好准备.
正如我在这个帖子中提到的,我倾向于使用Jersey来实现JAX-RS并且带有一个不错的REST客户端.好的是,如果使用JAX-RS实现RESTful资源,那么Jersey客户端可以重用实体提供程序,例如JAXB/XML/JSON/Atom等等 - 这样您就可以在服务器端重用相同的对象了用于客户端单元测试.
例如,这是来自Apache Camel项目的单元测试用例,它从RESTful资源(使用JAXB对象端点)查找XML有效负载.资源(uri)方法在此基类中定义,该基类仅使用Jersey客户端API.
例如
clientConfig = new DefaultClientConfig(); client = Client.create(clientConfig); resource = client.resource("http://localhost:8080"); // lets get the XML as a String String text = resource("foo").accept("application/xml").get(String.class);
顺便说一下,我希望JAX-RS的未来版本能够在Jersey中添加一个不错的客户端API
您可以使用标准Java SE API:
private void updateCustomer(Customer customer) { try { URL url = new URL("http://www.example.com/customers"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setInstanceFollowRedirects(false); connection.setRequestMethod("PUT"); connection.setRequestProperty("Content-Type", "application/xml"); OutputStream os = connection.getOutputStream(); jaxbContext.createMarshaller().marshal(customer, os); os.flush(); connection.getResponseCode(); connection.disconnect(); } catch(Exception e) { throw new RuntimeException(e); } }
或者,您可以使用由JAX-RS实现(如Jersey)提供的REST客户端API.这些API更易于使用,但在类路径上需要额外的jar.
WebResource resource = client.resource("http://www.example.com/customers"); ClientResponse response = resource.type("application/xml");).put(ClientResponse.class, "... 有关更多信息,请参阅
http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-55.html
一条简单的休息电话13线,**2018年**,听起来太多了......
4> Johan..:如果您只想调用REST服务并解析响应,可以尝试Rest Assured
// Make a GET request to "/lotto" String json = get("/lotto").asString() // Parse the JSON response ListwinnderIds = with(json).get("lotto.winners.winnerId"); // Make a POST request to "/shopping" String xml = post("/shopping").andReturn().body().asString() // Parse the XML Node category = with(xml).get("shopping.category[0]");
5> 小智..:您还可以检查具有完整客户端功能的Restlet,更多面向REST的低级库,例如HttpURLConnection或Apache HTTP Client(我们可以利用它作为连接器).
最诚挚的问候,Jerome Louvel
6> 小智..:你可以试试Rapa.请告诉我们您的反馈意见.并随时记录问题或预期功能.
7> Yasitha Chin..:我最近在广场试过了Retrofit Library,非常棒,你可以很容易地调用你的其他API.基于注释的配置允许我们摆脱大量的锅炉板编码.
8> Ophir Radnit..:我想指出另外两个选择:
Restfulie基于VRaptor Web框架,具有服务器和客户端实现,具有非常好的超媒体支持.
RESTEasy具有基于JAX-RS代理的客户端实现.
9> JeeBee..:我使用Apache HTTPClient来处理所有HTTP方面的事情.
我为XML内容编写XML SAX解析器,将XML解析为对象模型.我相信Axis2也暴露了XML - >模型方法(Axis 1隐藏了这部分,令人讨厌).XML生成器非常简单.
在我看来,编码并不需要很长时间,效率也很高.
在我看来,这是做REST的最糟糕方式.当你拥有像JAXB和Jackson这么多的选项时,手动处理Java中的序列化是浪费时间.即使加载整个文档并使用XPath也比SAX略慢,并且与获取XML(网络速度)相比没什么.
10> 小智..:当与Retrofit结合使用时,OkHttp既轻巧又强大。这对于一般的Java使用以及Android都适用。
OkHttp:http : //square.github.io/okhttp/
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); OkHttpClient client = new OkHttpClient(); String post(String url, String json) throws IOException { RequestBody body = RequestBody.create(JSON, json); Request request = new Request.Builder() .url(url) .post(body) .build(); Response response = client.newCall(request).execute(); return response.body().string(); }改造:http : //square.github.io/retrofit/
public interface GitHubService { @GET("/users/{user}/repos") Call> listRepos(@Path("user") String user); }