RESTful вызов в Java


150

Я собираюсь сделать RESTful-вызов в Java. Однако я не знаю, как сделать звонок. Нужно ли использовать URLConnection или другие? Может кто-нибудь помочь мне. Спасибо.


Это зависит от того, как вы делаете остальные звонки в вашем приложении. Используете ли вы реализацию JaxRS? Конкретный? Вы делаете запросы вручную?
Колин Хеберт,

@ Колин Хеберт, спасибо за ваш ответ. Но я понятия не имею о вызове RESTful. Не могли бы вы дать мне больше информации о различных частях вызова RESTful.
Вопросы

оформить заказ http отдыхающий клиент нажмите здесь
Gaurav J

Ответы:


91

Если вы звоните в службу RESTful от поставщика услуг (например, Facebook, Twitter), вы можете сделать это с любым вкусом по вашему выбору:

Если вы не хотите использовать внешние библиотеки, вы можете использовать java.net.HttpURLConnectionили javax.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

13
Я не изобретаю велосипед, я говорю, что вы можете использовать все, flavourчто захотите. Некоторые хотят по умолчанию URLConnection, некоторые хотят HttpClient. В любом случае, это для вас.
Бухаке Синди

@ Элитный джентльмен, спасибо за ваш ответ. После проверки всей библиотеки, я хочу использовать Apache HttpClient, не могли бы вы дать мне дополнительную информацию об этом?
Вопросы

@Questions, ссылка на примеры HttpClient 4, кажется, не работает, поэтому, если у вас есть какие-либо вопросы (каламбур ... лол), дайте мне знать ... Я занимаюсь этим почти ежедневно.
Бухаке Синди

Пожалуйста, покажите пример кода того, как использовать эти классы, а не просто отметьте их существование
Джонатан

150

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

В 99% случаев, когда люди используют термин REST, они действительно означают HTTP; они могут меньше заботиться о «ресурсах», «представлениях», «передачах состояний», «унифицированных интерфейсах», «гипермедиа» или любых других ограничениях или аспектах стиля архитектуры REST, определенных Fielding . Поэтому абстракции, предоставляемые различными средами REST, сбивают с толку и бесполезны.

Итак: вы хотите отправлять HTTP-запросы с использованием Java в 2015 году. Вам нужен API, который будет понятным, выразительным, интуитивно понятным, идиоматическим, простым. Что использовать? Я больше не использую Java, но последние несколько лет клиентская библиотека Java HTTP, которая показалась наиболее перспективной и интересной, - это OkHttp . Проверьте это.


Вы можете определенно взаимодействовать с веб-сервисами RESTful, используя URLConnectionили HTTPClient для кодирования HTTP-запросов.

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

Некоторые из наиболее зрелых вариантов Джерси , RESTEasy и Restlet .

Я больше всего знаком с Рестлет и Джерси, давайте посмотрим, как мы могли бы сделать 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.

Как я уже сказал, я больше всего знаком с Restlet, я использовал его во многих приложениях в течение многих лет, и я очень доволен этим. Это очень зрелая, надежная, простая, эффективная, активная и хорошо поддерживаемая среда. Я не могу говорить с Джерси или RESTEasy, но у меня сложилось впечатление, что они оба также являются солидным выбором.


2
Но все равно отличный пост. И я должен согласиться с тем, что «в 99% случаев, когда люди используют термин REST, они действительно означают HTTP; ... Поэтому абстракции, предоставляемые различными средами REST, сбивают с толку и бесполезны».
AlexD

2
В вашем примере на Джерси, где / как используется объект Form? Он создан, но, похоже, ничего не добавляет к примеру.
Splunbob

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
OP не создает приложение RESTful, он выполняет вызовы RESTful, то есть как вызов ресурса метода Twitter API.
Бухаке Синди

@Qwerky - я думаю, что было бы полезно указать, почему вы рекомендуете Джерси в своем ответе.
Дэнни Буллис

7

Я хочу поделиться своим личным опытом вызова REST WS с вызовом Post JSON:

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.