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.
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.
Respuestas:
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.HttpURLConnection
o 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 URLConnection
y 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 InputStream
y puede usarla como se mencionó anteriormente.
Documentación sobre HttpClient: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html
flavour
que quieras. Algunos quieren el valor predeterminado URLConnection
, algunos quieren HttpClient
. De cualquier manera, está ahí para que lo uses.
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 URLConnection
o 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 POST
solicitud con ambas 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());
}
Por supuesto, las solicitudes GET son aún más simples, y también puede especificar cosas como etiquetas de entidad y Accept
encabezados, 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.
Esto es muy complicado en Java, por lo que sugeriría usar la RestTemplate
abstracción de Spring :
String result =
restTemplate.getForObject(
"http://example.com/hotels/{hotel}/bookings/{booking}",
String.class,"42", "21"
);
Referencia:
RestTemplate
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();
}
}
Hay varias API RESTful alrededor. Yo recomendaría Jersey;
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
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);
}
}
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();
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();
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);
Veo muchas respuestas, esto es lo que estamos usando en 2020 WebClient , y BTW RestTemplate se quedará obsoleto. (puede verificar esto) RestTemplate será desaprobado
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();
}