Java中的RESTful调用

Que*_*ons 137 java rest

我将在Java中进行RESTful调用.但是,我不知道如何拨打电话.我需要使用URLConnection还是其他人?谁能帮我.谢谢.

Avi*_*lax 145

更新:我写下面的答案已经差不多5年了; 今天我有不同的看法.

99%的人在使用REST这个术语时,他们的确意味着HTTP; 他们可能不太关心"资源","表示","状态转移","统一接口","超媒体"或Fielding确定的REST架构风格的任何其他约束或方面.因此,各种REST框架提供的抽象是令人困惑和无益的.

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


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

然而,通常更期望使用库或框架,其提供专门为此目的而设计的更简单且更语义的API.这使代码更易于编写,读取和调试,并减少了重复工作.这些框架通常实现一些很好的功能,这些功能在低级库中不一定存在或易于使用,例如内容协商,缓存和身份验证.

一些最成熟的选项是Jersey,RESTEasyRestlet.

我最熟悉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());
}
Run Code Online (Sandbox Code Playgroud)

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());
}
Run Code Online (Sandbox Code Playgroud)

当然,GET请求甚至更简单,你也可以指定实体标签和Accept标题之类的东西,但希望这些例子非常有用,但不是太复杂.

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

我发现Restlet API更具语义性,因此更清晰,但YMMV.

正如我所说的,我最熟悉Restlet,我已经在很多应用程序中使用它多年了,我对它非常满意.它是一个非常成熟,强大,简单,有效,活跃且受到良好支持的框架.我不能和Jersey或RESTEasy说话,但我的印象是他们都是不错的选择.

  • 过时了.请参阅:https://jersey.java.net/documentation/latest/client.html (3认同)
  • 但仍然是一个伟大的帖子.我必须同意"99%的人使用REST这个术语,他们的确意味着HTTP; ......各种REST框架提供的抽象因此令人困惑和无益." (2认同)
  • 在您的 Jersey 示例中,Form 对象在哪里/如何使用?它已创建,但似乎没有向示例添加任何内容。 (2认同)

Buh*_*ndi 84

如果您从服务提供商(例如Facebook,Twitter)调用RESTful服务,您可以使用您选择的任何风格来执行此操作:

如果您不想使用外部库,则可以使用java.net.HttpURLConnectionjavax.net.ssl.HttpsURLConnection(对于SSL),但这是在工厂类型模式中封装的调用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

  • 它不是重新发明轮子,我说你可以使用你想要的任何"味道".有些人想要默认的`URLConnection`,有些人想要`HttpClient`.无论哪种方式,它都可供您使用. (12认同)
  • 不要重新发明轮子,使用现有的RESTful实现之一. (3认同)

Sea*_*oyd 27

这在java中非常复杂,这就是为什么我建议使用Spring的RestTemplate抽象:

String result = 
restTemplate.getForObject(
    "http://example.com/hotels/{hotel}/bookings/{booking}",
    String.class,"42", "21"
);
Run Code Online (Sandbox Code Playgroud)

参考:


jit*_*ter 23

如果您只需要从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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Qwerky客户端API库通常违反REST约束.他们引入了太多的耦合.从长远来看,使用良好的HTTP库是一个更好的选择. (2认同)

Qwe*_*rky 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

  • OP没有创建RESTful应用程序,他正在进行RESTful调用,即调用Twitter API方法资源. (5认同)

小智 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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Joo*_*ter 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();
Run Code Online (Sandbox Code Playgroud)


Hem*_*min 5

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

添加以下依赖项。

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)