Java中的RESTful调用


150

我将用Java进行RESTful调用。但是,我不知道如何拨打电话。我是否需要使用URLConnection或其他?谁能帮我。谢谢。


这取决于您如何在应用程序中进行剩余调用。您是否使用JaxRS实现?一个特别的?您是在手动执行请求吗?
科林·赫伯特

@Colin Hebert,谢谢您的答复。但是我对RESTful电话一无所知。您能否给我更多有关RESTful调用的不同部分的信息。
问题

结帐http宁静的客户端请单击此处
Gaurav J

Answers:


91

如果要从服务提供商(例如Facebook,Twitter)调用RESTful服务,则可以选择以下任意一种方式:

如果您不想使用外部库,则可以使用java.net.HttpURLConnectionjavax.net.ssl.HttpsURLConnection(对于SSL),但这是封装在中的Factory类型模式中的调用java.net.URLConnection。要接收结果,您必须connection.getInputStream()返回InputStream。然后,您将必须将输入流转换为字符串,并将字符串解析为它的代表对象(例如XML,JSON等)。

另外,Apache HttpClient(最新版本为4)。它比Java的默认值更稳定和健壮URLConnection,并且支持大多数(如果不是全部)HTTP协议(以及可以将其设置为严格模式)。您的回复仍然会存在InputStream,您可以按照上述方式使用它。


HttpClient上的文档:http : //hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html


5
不要重新发明轮子,使用现有的RESTful实现之一。
Qwerky 2010年

13
这并不是在重新设计轮子,而是说您可以使用任何flavour想要的东西。有些人想要默认值URLConnection,有些人想要HttpClient。无论哪种方式,它都可以供您使用。
Buhake Sindi

@精英绅士,谢谢您的答复。在检查完所有库之后,我想使用Apache HttpClient,您介意给我更多有关此库的参考吗?
问题

@问题,指向HttpClient 4示例的链接似乎已断开,因此,如果您有任何问题(双关语...大声笑),请告诉我....我几乎每天都在处理它。
Buhake Sindi

请显示如何使用这些类的示例代码,而不是仅仅注意它们的存在
Jonathan

150

更新:自从我在下面写下答案以来已经快5年了;今天我有不同的看法。

人们有99%的时间使用“ REST”一词,实际上是HTTP。他们可能不太在乎Fielding识别的 “资源”,“表示形式”,“状态转移”,“统一接口”,“超媒体”或REST体系结构样式的任何其他约束或方面。因此,各种REST框架提供的抽象令人困惑且无益。

因此:您想在2015年使用Java发送HTTP请求。您想要一个清晰,表达,直观,习惯,简单的API。使用什么?我不再使用Java,但是在过去的几年中,似乎最有前途和最有趣的Java HTTP客户端库是OkHttp。看看这个。


您绝对可以通过使用URLConnectionHTTPClient编码HTTP请求来与RESTful Web服务进行交互。

但是,通常更需要使用一个库或框架来提供专门为此目的设计的更简单,更语义化的API。这使代码更易于编写,阅读和调试,并减少了重复劳动。这些框架通常会实现一些很棒的功能,这些功能不一定会在低级库中呈现或易于使用,例如内容协商,缓存和身份验证。

一些最成熟的选项是JerseyRESTEasyRestlet

我对Restlet和Jersey最熟悉,让我们看看如何POST使用这两个API发出请求。

泽西岛的例子

Form form = new Form();
form.add("x", "foo");
form.add("y", "bar");

Client client = ClientBuilder.newClient();

WebTarget resource = client.target("http://localhost:8080/someresource");

Builder request = resource.request();
request.accept(MediaType.APPLICATION_JSON);

Response response = request.get();

if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
    System.out.println("Success! " + response.getStatus());
    System.out.println(response.getEntity());
} else {
    System.out.println("ERROR! " + response.getStatus());    
    System.out.println(response.getEntity());
}

Restlet示例

Form form = new Form();
form.add("x", "foo");
form.add("y", "bar");

ClientResource resource = new ClientResource("http://localhost:8080/someresource");

Response response = resource.post(form.getWebRepresentation());

if (response.getStatus().isSuccess()) {
    System.out.println("Success! " + response.getStatus());
    System.out.println(response.getEntity().getText());
} else {
    System.out.println("ERROR! " + response.getStatus());
    System.out.println(response.getEntity().getText());
}

当然,GET请求甚至更简单,您还可以指定诸如实体标签和Accept标头之类的东西,但希望这些示例有用而平凡但不太复杂。

如您所见,Restlet和Jersey具有相似的客户端API。我相信它们是在同一时间发展的,因此相互影响。

我发现Restlet API更具语义,因此更加清晰,但是YMMV。

正如我所说,我对Restlet最为熟悉,我已经在许多应用程序中使用了多年,对此我感到非常满意。这是一个非常成熟,健壮,简单,有效,活跃且得到良好支持的框架。我无法与Jersey或RESTEasy通话,但我的印象是它们都是不错的选择。


2
但仍然是一个很好的职位。我必须同意“ 99%的情况下,人们使用REST这个术语时,它们的实际含义是HTTP; ...因此,各种REST框架提供的抽象令人困惑且毫无用处。”
AlexD

2
在您的Jersey示例中,Form对象在哪里/如何使用?它已创建,但似乎未向示例添加任何内容。
splungebob


24

如果您只需要从Java对REST服务进行简单调用,则可以使用以下代码

/*
 * Stolen from http://xml.nig.ac.jp/tutorial/rest/index.html
 * and http://www.dr-chuck.com/csev-blog/2007/09/calling-rest-web-services-from-java/
*/
import java.io.*;
import java.net.*;

public class Rest {

    public static void main(String[] args) throws IOException {
        URL url = new URL(INSERT_HERE_YOUR_URL);
        String query = INSERT_HERE_YOUR_URL_PARAMETERS;

        //make connection
        URLConnection urlc = url.openConnection();

        //use post mode
        urlc.setDoOutput(true);
        urlc.setAllowUserInteraction(false);

        //send query
        PrintStream ps = new PrintStream(urlc.getOutputStream());
        ps.print(query);
        ps.close();

        //get result
        BufferedReader br = new BufferedReader(new InputStreamReader(urlc
            .getInputStream()));
        String l = null;
        while ((l=br.readLine())!=null) {
            System.out.println(l);
        }
        br.close();
    }
}

1
周围有一些非常不错的REST API,我建议您使用一个,而不是重新发明轮子。
Qwerky 2010年

正如我所说:复杂如地狱。(不,我没有对此表示反对,这是一个非常有效的解决方案)
肖恩·帕特里克·弗洛伊德

4
@Qwerky客户端API库通常违反REST约束。它们引入了太多的耦合。从长远来看,使用一个好的HTTP库是一个更好的选择。
Darrel Miller

10

周围有几种RESTful API。我会推荐泽西岛;

https://jersey.java.net/

客户端API文档在这里;

https://jersey.java.net/documentation/latest/index.html


下面评论中的OAuth文档更新位置是一个无效链接,已移动到 https://jersey.java.net/nonav/documentation/latest/security.html#d0e12334


6
OP并没有创建RESTful应用程序,而是在进行RESTful调用,即调用Twitter API方法资源。
Buhake Sindi

@Qwerky-我认为将答案推荐给新泽西的原因会有所帮助。
丹尼·布利斯

7

我想分享我的个人经验,并通过Post JSON调用来调用REST WS:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;

public class HWS {

    public static void main(String[] args) throws IOException {
        URL url = new URL("INSERT YOUR SERVER REQUEST");
        //Insert your JSON query request
        String query = "{'PARAM1': 'VALUE','PARAM2': 'VALUE','PARAM3': 'VALUE','PARAM4': 'VALUE'}";
        //It change the apostrophe char to double colon char, to form a correct JSON string
        query=query.replace("'", "\"");

        try{
            //make connection
            URLConnection urlc = url.openConnection();
            //It Content Type is so importan to support JSON call
            urlc.setRequestProperty("Content-Type", "application/xml");
            Msj("Conectando: " + url.toString());
            //use post mode
            urlc.setDoOutput(true);
            urlc.setAllowUserInteraction(false);

            //send query
            PrintStream ps = new PrintStream(urlc.getOutputStream());
            ps.print(query);
            Msj("Consulta: " + query);
            ps.close();

            //get result
            BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
            String l = null;
            while ((l=br.readLine())!=null) {
                Msj(l);
            }
            br.close();
        } catch (Exception e){
            Msj("Error ocurrido");
            Msj(e.toString());
        }
    }

    private static void Msj(String texto){
        System.out.println(texto);
    }
}

5

您可以签出CXF。您可以在此处访问JAX-RS文章

调用就这样简单(引用):

BookStore store = JAXRSClientFactory.create("http://bookstore.com", BookStore.class);
// (1) remote GET call to http://bookstore.com/bookstore
Books books = store.getAllBooks();
// (2) no remote call
BookResource subresource = store.getBookSubresource(1);
// {3} remote GET call to http://bookstore.com/bookstore/1
Book b = subresource.getDescription();

5

实际上,这“在Java中非常复杂”:

来自:https : //jersey.java.net/documentation/latest/client.html

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://foo").path("bar");
Invocation.Builder invocationBuilder = target.request(MediaType.TEXT_PLAIN_TYPE);
Response response = invocationBuilder.get();

4

最简单的解决方案将使用Apache http客户端库。请参阅以下示例代码。.此代码使用基本安全性进行身份验证。

添加以下依赖项。

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
Credentials credentials = new UsernamePasswordCredentials("username", "password");
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build();
HttpPost request = new HttpPost("https://api.plivo.com/v1/Account/MAYNJ3OT/Message/");HttpResponse response = client.execute(request);
    // Get the response
    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    String line = "";
    while ((line = rd.readLine()) != null) {    
    textView = textView + line;
    }
    System.out.println(textView);


-1

您可以这样使用Async Http Client(该库还支持WebSocket协议):

    String clientChannel = UriBuilder.fromPath("http://localhost:8080/api/{id}").build(id).toString();

    try (AsyncHttpClient asyncHttpClient = new AsyncHttpClient())
    {
        BoundRequestBuilder postRequest = asyncHttpClient.preparePost(clientChannel);
        postRequest.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
        postRequest.setBody(message.toString()); // returns JSON
        postRequest.execute().get();
    }

它不起作用(不能实例化ASyncHttpClient)。
Java Main
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.