RESTful дзвінок на Java


150

Я збираюся здійснити RESTful дзвінок на Java. Однак я не знаю, як зателефонувати. Чи потрібно використовувати URLConnection чи інші? Хтось може мені допомогти. спасибі.


Це залежить від того, як ви виконуєте дзвінки на відпочинок у вашій програмі. Чи використовуєте Ви реалізацію JaxRS? Конкретний? Ви робите запити вручну?
Колін Геберт

@Colin Hebert, дякую за відповідь. Але я не маю жодних уявлень про RESTful call. чи можете ви дати мені більше інформації про різні частини RESTful дзвінка.
Питання

замовити http спокійний клієнт натисніть тут
Gaurav J

Відповіді:


91

Якщо ви зателефонуєте на послугу RESTful від постачальника послуг (наприклад, Facebook, Twitter), ви можете це зробити з будь-яким смаком :

Якщо ви не хочете використовувати зовнішні бібліотеки, ви можете використовувати java.net.HttpURLConnectionабо javax.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


5
Не вигадуйте колесо, використовуйте одну з існуючих реалізацій RESTful.
Qwerky

13
Це не винахід колеса, я кажу, що ви можете використовувати все, flavourщо завгодно. Деякі хочуть за замовчуванням URLConnection, деякі хочуть HttpClient. У будь-якому випадку, це для вас, щоб використовувати.
Buhake Sindi

@ Елітний джентльмен, дякую за вашу відповідь. Перевіривши всю бібліотеку, я хочу скористатися Apache HttpClient, чи не заперечуєте ви більше ознайомитися з цим питанням?
Запитання

@Попитання, посилання на приклади HttpClient 4, здається, порушено, тому якщо у вас є якісь запитання (каламбур призначений ... хай), дайте мені знати .... Я з цим займаюся майже щодня.
Buhake Sindi

Покажіть, будь ласка, приклад коду, як користуватися цими класами, а не просто зазначити їх існування
Джонатан

150

Оновлення: минуло майже 5 років, як я написав відповідь нижче; сьогодні я маю іншу точку зору.

99% часу, коли люди використовують термін REST, вони справді означають HTTP; вони можуть менше піклуватися про "ресурси", "уявлення", "передачі стану", "єдині інтерфейси", "гіпермедіа" або будь-які інші обмеження або аспекти стилю архітектури REST, визначені Fielding . Таким чином, абстракції, що надаються різними рамками REST, є заплутаними і не корисними.

Отже: ви хочете відправляти HTTP-запити за допомогою Java у 2015 році. Хочете, щоб API був зрозумілим, виразним, інтуїтивним, ідіоматичним, простим. Що використовувати? Я більше не використовую Java, але останні кілька років бібліотека клієнтів Java HTTP, яка здавалася найбільш перспективною і цікавою, - OkHttp . Перевір.


Ви можете однозначно взаємодіяти з RESTful веб-сервісами, використовуючи URLConnectionабо HTTPClient для кодування HTTP-запитів.

Однак, як правило, більш бажано використовувати бібліотеку або рамки, які надають більш простий і семантичний API, спеціально розроблений для цієї мети. Це полегшує запис, читання та налагодження коду та зменшує дублювання зусиль. Ці рамки, як правило, реалізують деякі чудові функції, які не обов'язково присутні або прості у використанні в бібліотеках нижчого рівня, таких як узгодження вмісту, кешування та автентифікація.

Одні з найбільш зрілих варіантів - Джерсі , RESTEasy та Рестлет .

Я найбільше знайомий з Рестлетом та Джерсі, давайте подивимось, як ми зробили б 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());
}

Приклад перестановки

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заголовки об'єктів , але, сподіваємось, ці приклади корисно нетривіальні, але не надто складні.

Як бачите, Рестлет та Джерсі мають подібні API клієнта. Я вважаю, що вони розроблялися приблизно в один і той же час, і тому впливали один на одного.

Я вважаю API Restlet трохи семантичнішим, а отже, трохи зрозумілішим, але YMMV.

Як я вже говорив, я найбільше знайомий з Рестлетом, я його використовував у багатьох програмах роками, і я дуже задоволений цим. Це дуже зрілий, надійний, простий, ефективний, активний та добре підтримуваний фреймворк. Я не можу розмовляти з Джерсі чи RESTEasy, але моє враження, що вони обидва - теж суцільний вибір.


2
Але все-таки чудовий пост. І я маю згоду з "99% часу, коли люди використовують термін REST, вони насправді мають на увазі HTTP; ... Абстракції, які надаються різними рамками REST, тому заплутані і не корисні".
AlexD

2
У вашому прикладі Джерсі, де / як використовується об’єкт Form? Він створений, але, схоже, нічого не додає до прикладу.
splungebob

29

У java це дуже складно, тому я б запропонував використовувати RestTemplateабстракцію Spring :

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

Довідка:


24

Якщо вам потрібно просто зателефонувати на службу REST з Java, ви використовуєте щось уздовж цієї лінії

/*
 * 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
Є кілька дійсно хороших API REST, я б рекомендував використовувати один, а не винаходити колесо.
Qwerky

як я вже сказав: складно, як пекло. (ні, я цього не заявляв, це ідеально правильне рішення)
Шон Патрік Флойд

4
@Qwerky Клієнтські бібліотеки API зазвичай є порушенням обмежень REST. Вони вводять занадто багато зв'язку. Використання хорошої бібліотеки HTTP - набагато кращий варіант у довгостроковій перспективі.
Даррел Міллер

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
ОП не створює програми RESTful, він здійснює RESTful дзвінки, тобто як дзвонить ресурс методу Twitter API.
Buhake Sindi

@Qwerky - Я думаю, було б корисно включити, чому ви рекомендуєте Джерсі у відповідь.
Danny Bullis

7

Я хочу поділитися своїм особистим досвідом, зателефонувавши на REST WS за допомогою дзвінка JSON Post:

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();


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

Ви можете використовувати Http-клієнт Async (бібліотека також підтримує протокол 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.