Połączenie RESTful w Javie

150

Mam zamiar wykonać wywołanie RESTful w Javie. Jednak nie wiem, jak zadzwonić. Czy muszę używać połączenia URL lub innych? Czy ktoś może mi pomóc. Dziękuję Ci.

pytania
źródło
Zależy to od tego, w jaki sposób wykonujesz połączenia resztowe w aplikacji. Czy korzystasz z implementacji JaxRS? Konkretny? Czy wykonujesz żądania ręcznie?
Colin Hebert,
@Colin Hebert, dziękuję za odpowiedź. Ale nie mam pomysłów na połączenie RESTful. czy możesz podać mi więcej informacji na temat różnych części połączenia RESTful.
Pytania
do kasy http restful client kliknij tutaj
Gaurav J

Odpowiedzi:

91

Jeśli dzwonisz do relaksującego usługi od usługodawcy (np Facebook, Twitter), można zrobić to z każdym smaku swojego wyboru:

Jeśli nie chcesz używać bibliotek zewnętrznych, możesz użyć java.net.HttpURLConnectionlub javax.net.ssl.HttpsURLConnection(dla protokołu SSL), ale jest to wywołanie hermetyzowane we wzorcu typu Factory w programie java.net.URLConnection. Aby otrzymać wynik, będziesz musiał zwrócić connection.getInputStream()ci plik InputStream. Będziesz wtedy musiał przekonwertować strumień wejściowy na łańcuch i przeanalizować go na reprezentatywny obiekt (np. XML, JSON, itp.).

Alternatywnie Apache HttpClient (wersja 4 jest najnowszą). Jest bardziej stabilny i niezawodny niż domyślny java URLConnectioni obsługuje większość (jeśli nie wszystkie) protokołów HTTP (a także może być ustawiony na tryb ścisły). Twoja odpowiedź będzie nadal dostępna InputStreami możesz jej użyć, jak wspomniano powyżej.


Dokumentacja dotycząca HttpClient: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html

Buhake Sindi
źródło
5
Nie odkrywaj na nowo koła, użyj jednej z istniejących implementacji RESTful.
Qwerky
13
To nie jest odkrywanie koła na nowo, mówię, że możesz używać wszystkiego flavour, co chcesz. Niektórzy chcą domyślnego URLConnection, niektórzy chcą HttpClient. Tak czy inaczej, możesz z niego skorzystać.
Buhake Sindi
@ Elitarny dżentelmen, dziękuję za odpowiedź. Po sprawdzeniu całej biblioteki chcę użyć Apache HttpClient, czy mógłbyś podać mi więcej informacji na temat tego?
Pytania
@Questions, link do przykładów HttpClient 4 wydaje się być uszkodzony, więc jeśli masz jakieś pytania (gra słów przeznaczona ... lol), daj mi znać ... Zajmuję się tym prawie codziennie.
Buhake Sindi
Proszę pokazać przykładowy kod, jak korzystać z tych klas, zamiast tylko odnotowywać ich istnienie
Jonathan
150

Aktualizacja: Minęło prawie 5 lat, odkąd napisałem odpowiedź poniżej; dziś mam inną perspektywę.

W 99% przypadków, kiedy ludzie używają terminu REST, naprawdę mają na myśli HTTP; mniej obchodzą ich „zasoby”, „reprezentacje”, „transfery stanu”, „jednolite interfejsy”, „hipermedia” czy jakiekolwiek inne ograniczenia lub aspekty stylu architektury REST zidentyfikowane przez Fieldinga . Abstrakcje dostarczane przez różne ramy REST są zatem mylące i nieprzydatne.

A więc: chcesz wysyłać żądania HTTP za pomocą Javy w 2015 roku. Chcesz API, które jest przejrzyste, wyraziste, intuicyjne, idiomatyczne, proste. Czego używać? Nie używam już Javy, ale przez ostatnie kilka lat biblioteką klienta HTTP, która wydawała się najbardziej obiecująca i interesująca, jest OkHttp . Sprawdź to.


Z pewnością można współdziałać z usługami sieci Web RESTful, używając URLConnectionlub HTTPClient do kodowania żądań HTTP.

Jednak generalnie bardziej pożądane jest użycie biblioteki lub struktury, która zapewnia prostsze i bardziej semantyczne API zaprojektowane specjalnie do tego celu. Ułatwia to pisanie, odczytywanie i debugowanie kodu oraz ogranicza powielanie pracy. Te struktury zazwyczaj implementują kilka wspaniałych funkcji, które niekoniecznie są obecne lub łatwe w użyciu w bibliotekach niższego poziomu, takich jak negocjowanie zawartości, buforowanie i uwierzytelnianie.

Niektóre z najbardziej dojrzałych opcji to Jersey , RESTEasy i Restlet .

Najbardziej znam Restlet i Jersey, spójrzmy, jak wykonalibyśmy POSTżądanie za pomocą obu interfejsów API.

Przykład Jersey

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

Przykład restletu

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

Oczywiście żądania GET są jeszcze prostsze i możesz również określić takie rzeczy, jak tagi encji i Acceptnagłówki, ale mam nadzieję, że te przykłady są pożytecznie nietrywialne, ale niezbyt złożone.

Jak widać, Restlet i Jersey mają podobne interfejsy API klienta. Uważam, że powstały mniej więcej w tym samym czasie i dlatego wpływały na siebie nawzajem.

Uważam, że Restlet API jest trochę bardziej semantyczny, a zatem trochę jaśniejszy, ale YMMV.

Jak powiedziałem, najlepiej znam Restlet, od lat używam go w wielu aplikacjach i jestem z niego bardzo zadowolony. To bardzo dojrzała, solidna, prosta, skuteczna, aktywna i dobrze obsługiwana platforma. Nie mogę rozmawiać z Jersey lub RESTEasy, ale mam wrażenie, że oba są również solidnymi wyborami.

Avi Flax
źródło
2
Ale nadal świetny post. I muszę się zgodzić z „99% przypadków, gdy ludzie używają terminu REST, naprawdę mają na myśli HTTP; ... Abstrakcje dostarczane przez różne frameworki REST są zatem mylące i niepomocne”.
AlexD
2
W twoim przykładzie z Jersey, gdzie / jak jest używany obiekt Form? Został utworzony, ale wydaje się, że nic nie dodaje do przykładu.
splungebob
24

Jeśli potrzebujesz tylko wykonać proste połączenie z usługą REST z javy, użyj czegoś takiego

/*
 * 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();
    }
}
drganie
źródło
1
Istnieje kilka naprawdę dobrych interfejsów API REST, polecam używanie jednego zamiast wymyślania koła na nowo.
Qwerky,
jak powiedziałem: skomplikowane jak diabli. (nie, nie przegłosowałem tego, jest to całkowicie poprawne rozwiązanie)
Sean Patrick Floyd
4
Biblioteki API @Qwerky po stronie klienta są zwykle naruszeniem ograniczeń REST. Wprowadzają zbyt wiele sprzężeń. Korzystanie z dobrej biblioteki HTTP jest w dłuższej perspektywie znacznie lepszą opcją.
Darrel Miller,
10

Istnieje kilka interfejsów API RESTful. Poleciłbym Jersey;

https://jersey.java.net/

Dokumentacja API klienta jest tutaj;

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


Lokalizacja aktualizacji dla dokumentów OAuth w komentarzu poniżej to martwy link i została przeniesiona do https://jersey.java.net/nonav/documentation/latest/security.html#d0e12334

Qwerky
źródło
6
OP nie tworzy aplikacji RESTful, wykonuje wywołania RESTful, np. Jak wywołanie zasobu metody Twitter API.
Buhake Sindi
@Qwerky - Myślę, że warto byłoby zawrzeć w odpowiedzi, dlaczego polecasz Jersey.
Danny Bullis
7

Chcę podzielić się moim osobistym doświadczeniem, dzwoniąc do REST WS z wywołaniem 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);
    }
}
Lisandro
źródło
5

Możesz sprawdzić CXF . Możesz odwiedzić artykuł JAX-RS tutaj

Dzwonienie jest tak proste, jak to (cytat):

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();
Joopiter
źródło
5

Rzeczywiście, jest to „bardzo skomplikowane w Javie”:

Od: 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();
JRun
źródło
4

Najprostsze rozwiązanie będzie korzystać z biblioteki klienta HTTP Apache. zobacz następujący przykładowy kod .. ten kod wykorzystuje podstawowe zabezpieczenia do uwierzytelniania.

Dodaj następującą zależność.

<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);
Hemin
źródło
1

Widzę wiele odpowiedzi, oto, czego używamy w 2020 WebClient , a BTW RestTemplate zostanie wycofany. (można to sprawdzić) RestTemplate zostanie wycofany

Francis Raj
źródło
Zamiast podawać link, czy możesz dodać wyjaśnienie tutaj?
Kishan Bharda
-1

Możesz użyć Async Http Client (biblioteka obsługuje również protokół WebSocket ) w następujący sposób:

    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();
    }
kayz1
źródło
to nie działa (nie można uruchomić ASyncHttpClient).
Java Main