Des clients REST pour Java?
avec JSR 311 et ses implémentations, nous avons un puissant standard pour exposer les objets Java via Rest. Cependant, du côté du client, il semble qu'il manque quelque chose qui est comparable à Apache Axis pour SOAP - quelque chose qui cache le service web et renvoie les données de manière transparente vers des objets Java.
comment créer des clients Java RESTful? En utilisant HTTPConnection et l'analyse manuelle du résultat? Ou clients spécialisés pour par exemple Jersey Ou Apache CXR?
18 réponses
C'est une vieille question (2008) il y a donc beaucoup plus d'options aujourd'hui qu'il y a eu ensuite:
- Apache CXF a trois différents RESTE les options du Client
- Jersey (mentionné ci-dessus).
- Spring a aussi son propre appelé RestTemplate
- Commons HTTP Client construisez vos propres projets Java.
mise à jour circa 2014:
-
Async-http-client by Sonatype. Ning Async-http-client .
Le nouvel enfant sur le bloc qui fournit le soutien NIO (bien que honnêtement je ne pense pas que cela améliore vraiment la performance pour les clients comme il le fait les serveurs).
- Apache HTTP Components (4.2) adaptateur Fluent - meilleur que le Client HTTP Old Commons 3 et plus facile à utiliser pour construire votre propre client REST. Vous devrez utiliser quelque chose comme Jackson pour JSON parsing support et vous pouvez utiliser HTTP composants URIBuilder de construire ressource Uri semblable à Jersey/JAX-RS Reste client. Les composants HTTP prennent également en charge NIO, mais je doute que vous obteniez de meilleures performances que BIO étant donné la nature de requête courte de REST.
mise à jour 2016 :
- OkHttp - prend en charge les nouveaux protocoles HTTP (SPDY et HTTP2). Fonctionne sur Android. Malheureusement, il n' ne pas offrir une véritable option async basée sur une boucle de réacteur (voir les composants ning et HTTP ci-dessus). Cependant, si vous utilisez le nouveau protocole HTTP2, cela posera moins de problèmes (en supposant que le nombre de connexions pose problème).
- Retrofit - va créer automatiquement des clients basés sur des talons d'interface similaires à certaines extensions Jersey et CXF. Utilise OkHttp.
- Apache Httpcomposants 5 will supposedly have HTTP2 support
Une mise en garde sur le choix de HTTP/REST clients. Assurez-vous de vérifier ce que votre empilement de framework utilise pour un client HTTP, comment il fait du threading, et idéalement utiliser le même client s'il en offre un. C'est si vous utilisez quelque chose comme Vert.x ou Play vous pouvez essayer d'utiliser son client de soutien pour participer à n'importe quel bus ou boucle de réacteur que le cadre fournit... sinon, préparez-vous à des questions de filetage éventuellement intéressantes.
comme je l'ai mentionné dans ce fil j'ai tendance à utiliser Jersey qui met en œuvre JAX-RS et est livré avec un client de repos agréable. La bonne chose est que si vous implémentez vos ressources RESTful en utilisant JAX-RS alors le client Jersey peut réutiliser les fournisseurs d'entités tels que pour JAXB/XML/JSON/Atom et ainsi de suite - de sorte que vous pouvez réutiliser les mêmes objets du côté du serveur que vous utilisez sur le test de l'Unité du côté du client.
par exemple ici est un cas d'essai unitaire du Apache Camel project qui recherche des charges utiles XML à partir d'une ressource RESTful (en utilisant les points D'extrémité d'objet JAXB). La méthode de la ressource(uri) est définie dans cette classe de base qui utilise simplement L'API Client De Jersey.
p.ex.
clientConfig = new DefaultClientConfig();
client = Client.create(clientConfig);
resource = client.resource("http://localhost:8080");
// lets get the XML as a String
String text = resource("foo").accept("application/xml").get(String.class);
BTW j'espère que la future version de JAX-RS ajouter une belle côté client de l'API sur le modèle de celui en Jersey
vous pouvez utiliser le standard Java SE API:
private void updateCustomer(Customer customer) {
try {
URL url = new URL("http://www.example.com/customers");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "application/xml");
OutputStream os = connection.getOutputStream();
jaxbContext.createMarshaller().marshal(customer, os);
os.flush();
connection.getResponseCode();
connection.disconnect();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
ou vous pouvez utiliser les API REST client fournies par les implémentations JAX-RS telles que Jersey. Ces API sont plus faciles à utiliser, mais nécessitent des pots supplémentaires sur votre chemin de classe.
WebResource resource = client.resource("http://www.example.com/customers");
ClientResponse response = resource.type("application/xml");).put(ClientResponse.class, "<customer>...</customer.");
System.out.println(response);
pour plus d'information voir:
vous pouvez aussi cocher Restlet qui dispose de toutes les fonctionnalités côté client, plus axées sur le repos que les bibliothèques de niveau inférieur comme HttpURLConnection ou Apache Client HTTP (que nous pouvons utiliser comme connecteurs).
meilleures salutations, Jerome Louvel
si vous souhaitez seulement invoquer un service de repos et analyser la réponse, vous pouvez essayer repos assuré
// Make a GET request to "/lotto"
String json = get("/lotto").asString()
// Parse the JSON response
List<String> winnderIds = with(json).get("lotto.winners.winnerId");
// Make a POST request to "/shopping"
String xml = post("/shopping").andReturn().body().asString()
// Parse the XML
Node category = with(xml).get("shopping.category[0]");
je voudrais souligner 2 autres options:
- "Restfulie , basé sur le cadre Web VRaptor, a des implémentations côté serveur et côté client avec un très bon support hypermédia.
- RESTEasy a une JAX-RS proxy client basé sur le la mise en œuvre.
j'ai récemment essayé Retrofit bibliothèque de square, son grand et vous pouvez appeler votre API de repos très facilement. La configuration basée sur l'Annotation nous permet de nous débarrasser de beaucoup de codage de plaques de chaudière.
J'utilise Apache HTTPClient pour gérer tout le côté HTTP des choses.
j'écris des analyseurs de SAX XML pour le contenu XML qui analyse le XML dans votre modèle d'objet. Je crois Qu'Axis2 expose aussi des méthodes de Modèles XML - > (L'Axe 1 A CACHÉ cette partie, de manière agaçante). Les générateurs XML sont trivialement simples.
Il ne faut pas longtemps pour le code, et est très efficace, à mon avis.
Essayer JdkRequest
à partir de jcabi-http (je suis développeur). C'est comme ça que ça marche:
String body = new JdkRequest("http://www.google.com")
.header("User-Agent", "it's me")
.fetch()
.body()
voir ce billet de blog pour plus de détails: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html
OkHttp est léger et puissant lorsqu'il est combiné avec la modernisation aussi bien. Cela fonctionne bien pour L'utilisation générale de Java ainsi que sur Android.
OkHttp : http://square.github.io/okhttp/
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
Retrofit : http://square.github.io/retrofit/
public interface GitHubService {
@GET("/users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
puisque personne ne l'a mentionné, en voici un autre: Feign , qui est utilisé par Spring Cloud .
bien qu'il soit simple de créer un client HTTP et de faire un reuest. Mais si vous voulez faire usage de certains clients générés automatiquement, vous pouvez faire usage de WADL pour décrire et générer du code.
vous pouvez utiliser RestDescribe pour générer et compiler WSDL, vous pouvez générer des clients en php, ruby, python, java et C# en utilisant ceci. Il génère du code propre et il y a un bon changement que vous devez modifier un peu après la génération de code, vous pouvez trouver bon documentation sous-jacents et les pensées derrière l'outil ici .
Il y a peu intéressant et utile WADL outils mentionnée sur wintermute.
j'ai écrit une bibliothèque qui établit une correspondance entre une interface java et un service de repos à distance JSON:
https://github.com/ggeorgovassilis/spring-rest-invoker
public interface BookService {
@RequestMapping("/volumes")
QueryResult findBooksByTitle(@RequestParam("q") String q);
@RequestMapping("/volumes/{id}")
Item findBookById(@PathVariable("id") String id);
}
Essayez de regarder les http-repos-client
https://github.com/g00dnatur3/http-rest-client
voici un exemple simple:
RestClient client = RestClient.builder().build();
String geocoderUrl = "http://maps.googleapis.com/maps/api/geocode/json"
Map<String, String> params = Maps.newHashMap();
params.put("address", "beverly hills 90210");
params.put("sensor", "false");
JsonNode node = client.get(geocoderUrl, params, JsonNode.class);
la bibliothèque s'occupe de la sérialisation et de la reliure json pour vous.
voici un autre exemple,
RestClient client = RestClient.builder().build();
String url = ...
Person person = ...
Header header = client.create(url, person);
if (header != null) System.out.println("Location header is:" + header.value());
et un dernier exemple,
RestClient client = RestClient.builder().build();
String url = ...
Person person = client.get(url, null, Person.class); //no queryParams
santé!
exemples de client jersey Rest:
Ajout de la dépendance:
<!-- jersey -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
oublie la méthode et passe deux paramètres:
Client client = Client.create();
WebResource webResource1 = client
.resource("http://localhost:10102/NewsTickerServices/AddGroup/"
+ userN + "/" + groupName);
ClientResponse response1 = webResource1.get(ClientResponse.class);
System.out.println("responser is" + response1);
GetMethod passer un paramètre et obtenir une réponse de liste:
Client client = Client.create();
WebResource webResource1 = client
.resource("http://localhost:10102/NewsTickerServices/GetAssignedUser/"+grpName);
//value changed
String response1 = webResource1.type(MediaType.APPLICATION_JSON).get(String.class);
List <String > Assignedlist =new ArrayList<String>();
JSONArray jsonArr2 =new JSONArray(response1);
for (int i =0;i<jsonArr2.length();i++){
Assignedlist.add(jsonArr2.getString(i));
}
au-dessus, il renvoie une liste que nous acceptons comme liste et la convertissons ensuite en JSON Array puis en Json Array pour List .
If Post Demande passant L'objet Json en paramètre:
Client client = Client.create();
WebResource webResource = client
.resource("http://localhost:10102/NewsTickerServices/CreateJUser");
// value added
ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class,mapper.writeValueAsString(user));
if (response.getStatus() == 500) {
context.addMessage(null, new FacesMessage("User already exist "));
}
vous pouvez utiliser java.net.URL
public class URL {
public URL(java.lang.String s)
throws java.net.MalformedURLException {}
public java.net.URLConnection
openConnection() throws java.io.IOException {}
...
}
à partir d'une URL, vous pouvez créer une HttpURLConnection qui vous permet d'invoquer specific
requests. Here’s an example of doing a simple GET request:
URL url = new URL("http://example.com/customers/1");
connection = (HttpURLConnection) getUrl.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
if (connection.getResponseCode() != 200) {
throw new RuntimeExceptioin("Operation failed: "
+ connection.getResponseCode());
}
System.out.println("Content-Type:
" + connection.getContentType());
BufferedReader reader = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
connection.disconnect();