Llamada RESTful en Java


150

Voy a hacer una llamada RESTful en Java. Sin embargo, no sé cómo hacer la llamada. ¿Necesito usar URLConnection u otros? Alguien puede ayudarme. gracias.


Depende de cómo hagas las llamadas de descanso en tu aplicación. ¿Utiliza una implementación JaxRS? Uno en particular? ¿Estás haciendo solicitudes manualmente?
Colin Hebert

@ Colin Hebert, gracias por tu respuesta. Pero no tengo ideas de la llamada RESTful. ¿podría darme más información sobre las diferentes partes de la llamada RESTful?
Preguntas del

pago http cliente tranquilo haga clic aquí
Gaurav J

Respuestas:


91

Si está llamando a un servicio RESTful de un proveedor de servicios (por ejemplo, Facebook, Twitter), puede hacerlo con cualquier sabor de su elección:

Si no desea usar bibliotecas externas, puede usar java.net.HttpURLConnectiono javax.net.ssl.HttpsURLConnection(para SSL), pero esa es una llamada encapsulada en un patrón de tipo Factory en java.net.URLConnection. Para recibir el resultado, tendrás connection.getInputStream()que devolver un InputStream. Luego tendrá que convertir su flujo de entrada a cadena y analizar la cadena en su objeto representativo (por ejemplo, XML, JSON, etc.).

Alternativamente, Apache HttpClient (la versión 4 es la última). Es más estable y robusto que el predeterminado de Java URLConnectiony admite la mayoría (si no todos) del protocolo HTTP (así como también se puede configurar en modo estricto). Su respuesta seguirá estando disponible InputStreamy puede usarla como se mencionó anteriormente.


Documentación sobre HttpClient: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html


55
No reinvente la rueda, use una de las implementaciones RESTful existentes.
Qwerky

13
No es reinventar la rueda, digo que puedes usar lo flavourque quieras. Algunos quieren el valor predeterminado URLConnection, algunos quieren HttpClient. De cualquier manera, está ahí para que lo uses.
Buhake Sindi

@ The Elite Gentleman, gracias por tu respuesta. Después de verificar la totalidad de la biblioteca, quiero usar el HttpClient de Apache, ¿te importaría darme más referencias sobre este?
preguntas

@Preguntas, el enlace a los ejemplos de HttpClient 4 parece estar roto, así que si tiene alguna pregunta (juego de palabras ... jajaja), avíseme ... lo trato casi a diario.
Buhake Sindi

Muestre un código de ejemplo de cómo usar estas clases, en lugar de simplemente señalar su existencia
Jonathan

150

Actualización: Han pasado casi 5 años desde que escribí la respuesta a continuación; Hoy tengo una perspectiva diferente.

El 99% de las veces cuando las personas usan el término REST, realmente se refieren a HTTP; podrían importarles menos los "recursos", las "representaciones", las "transferencias de estado", las "interfaces uniformes", los "hipermedia" o cualquier otra restricción o aspecto del estilo de arquitectura REST identificado por Fielding . Las abstracciones proporcionadas por varios marcos REST son, por lo tanto, confusas e inútiles.

Entonces: desea enviar solicitudes HTTP utilizando Java en 2015. Desea una API que sea clara, expresiva, intuitiva, idiomática, simple. ¿Qué usar? Ya no uso Java, pero durante los últimos años la biblioteca de cliente HTTP de Java que me ha parecido más prometedora e interesante es OkHttp . Echale un vistazo.


Definitivamente puede interactuar con los servicios web RESTful utilizando URLConnectiono HTTPClient para codificar las solicitudes HTTP.

Sin embargo, generalmente es más deseable usar una biblioteca o marco que proporcione una API más simple y semántica diseñada específicamente para este propósito. Esto hace que el código sea más fácil de escribir, leer y depurar, y reduce la duplicación de esfuerzos. Estos marcos generalmente implementan algunas características excelentes que no necesariamente están presentes o son fáciles de usar en bibliotecas de nivel inferior, como la negociación de contenido, el almacenamiento en caché y la autenticación.

Algunas de las opciones más maduras son Jersey , RESTEasy y Restlet .

Estoy más familiarizado con Restlet y Jersey, veamos cómo haríamos una POSTsolicitud con ambas API.

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

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

Por supuesto, las solicitudes GET son aún más simples, y también puede especificar cosas como etiquetas de entidad y Acceptencabezados, pero es de esperar que estos ejemplos sean útilmente no triviales pero no demasiado complejos.

Como puede ver, Restlet y Jersey tienen API de cliente similares. Creo que se desarrollaron al mismo tiempo y, por lo tanto, se influenciaron entre sí.

Creo que la API de Restlet es un poco más semántica y, por lo tanto, un poco más clara, pero YMMV.

Como dije, estoy más familiarizado con Restlet, lo he usado en muchas aplicaciones durante años y estoy muy contento con él. Es un marco muy maduro, robusto, simple, efectivo, activo y bien soportado. No puedo hablar con Jersey o RESTEasy, pero mi impresión es que ambos también son opciones sólidas.


2
Pero sigue siendo una gran publicación. Y tengo que estar de acuerdo con que "el 99% de las veces que las personas usan el término REST, realmente se refieren a HTTP; ... Las abstracciones proporcionadas por varios marcos REST son, por lo tanto, confusas e inútiles".
AlexD

2
En su ejemplo de Jersey, ¿dónde / cómo se usa el objeto Form? Está creado, pero no parece agregar nada al ejemplo.
splungebob


24

Si solo necesita hacer una simple llamada a un servicio REST desde Java, use algo a lo largo de esta línea

/*
 * 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
Hay algunas API REST realmente buenas, recomendaría usar una en lugar de reinventar la rueda.
Qwerky

como dije: complicado como el infierno. (no, no voté en contra de esto, es una solución perfectamente válida)
Sean Patrick Floyd

44
Las bibliotecas de API de @Qwerky Client suelen ser una violación de las restricciones REST. Introducen demasiado acoplamiento. Usar una buena biblioteca HTTP es una opción mucho mejor a largo plazo.
Darrel Miller

10

Hay varias API RESTful alrededor. Yo recomendaría Jersey;

https://jersey.java.net/

La documentación de la API del cliente está aquí;

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

La
ubicación de actualización para los documentos de OAuth en el comentario a continuación es un enlace inactivo y se ha movido a https://jersey.java.net/nonav/documentation/latest/security.html#d0e12334


66
El OP no está creando una aplicación RESTful, está haciendo llamadas RESTful, es decir, como llamar a un recurso de método API de Twitter.
Buhake Sindi

@Qwerky: creo que sería útil incluir por qué recomienda Jersey en su respuesta.
Danny Bullis

7

Quiero compartir mi experiencia personal, llamando a un REST WS con una llamada 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

Puedes ver el CXF . Puedes visitar el artículo JAX-RS aquí

Llamar es tan simple como esto (cita):

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

De hecho, esto es "muy complicado en Java":

De: 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

La solución más fácil utilizará la biblioteca de cliente http Apache. consulte el siguiente código de muestra ... este código utiliza seguridad básica para la autenticación.

Agregue la siguiente dependencia.

<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

Puede usar Async Http Client (la biblioteca también es compatible con el protocolo WebSocket ) así:

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

no funciona (no puede instanciar ASyncHttpClient).
Java Main
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.