Bagaimana Anda membuat klien REST untuk Java? [Tutup]

247

Dengan JSR 311 dan implementasinya kami memiliki standar yang kuat untuk mengekspos objek Java melalui REST. Namun di sisi klien tampaknya ada sesuatu yang hilang yang sebanding dengan Apache Axis untuk SOAP - sesuatu yang menyembunyikan layanan web dan marshal data secara transparan kembali ke objek Java.

Bagaimana Anda membuat klien Java RESTful? Menggunakan HTTPConnection dan penguraian hasil secara manual? Atau klien khusus untuk mis. Jersey atau Apache CXR?

Yaba
sumber
Baru saja menemukan Apache Wink di Apache Incubator. Bisa jadi proyek yang menarik untuk membuat server dan klien REST.
Yaba
2
lihat ini: igorpolevoy.blogspot.com/2011/01/java-rest-with-ease.html terima kasih igor
ipolevoy
Lihat [Istirahat] ( code.google.com/p/resting ). Ia berjanji untuk memanggil layanan REST dan membuat daftar objek dari respons XML / JSON / YAML dalam satu langkah.
neel
Istirahat memiliki masalah dengan permintaan POST.
RyanBrady
2
Anda dapat melakukannya dengan cara yang sangat sederhana dengan resteasy (oleh Jboss). Saya menulis posting blog tentang bagaimana mengembangkan klien Java REST jika Anda ingin panduan memulai. Lagi pula, ada ratusan alternatif di Jawa.
Guido

Jawaban:

204

Ini adalah pertanyaan lama (2008) sehingga ada lebih banyak opsi sekarang daripada sebelumnya:

UPDATES (proyek masih aktif pada tahun 2020):

  • Apache HTTP Components (4.2) Adaptor yang lancar - Penggantian dasar untuk JDK, digunakan oleh beberapa kandidat lain dalam daftar ini. Lebih baik daripada Commons HTTP Client 3 lama dan lebih mudah digunakan untuk membangun klien REST Anda sendiri. Anda harus menggunakan sesuatu seperti Jackson untuk dukungan parsing JSON dan Anda dapat menggunakan komponen HTTP URIBuilder untuk membuat URI sumber daya yang serupa dengan klien Jersey / JAX-RS Rest. Komponen HTTP juga mendukung NIO tetapi saya ragu Anda akan mendapatkan kinerja yang lebih baik daripada BIO mengingat permintaan pendek dari REST. Apache HttpComponents 5 memiliki dukungan HTTP / 2.
  • OkHttp - Penggantian dasar untuk JDK, mirip dengan komponen http, digunakan oleh beberapa kandidat lain dalam daftar ini. Mendukung protokol HTTP yang lebih baru (SPDY dan HTTP2). Bekerja di Android. Sayangnya itu tidak menawarkan opsi async berbasis reaktor-loop sejati (lihat Ning dan komponen HTTP di atas). Namun jika Anda menggunakan protokol HTTP2 yang lebih baru, ini bukan masalah (dengan asumsi jumlah koneksi bermasalah).
  • Ning Async-http-client - menyediakan dukungan NIO. Sebelumnya dikenal sebagai Async-http-client oleh Sonatype .
  • Feign wrapper untuk klien http tingkat rendah (okhttp, apache httpcomponents). Klien otomatis dibuat berdasarkan potongan antarmuka yang mirip dengan beberapa ekstensi Jersey dan CXF. Integrasi pegas yang kuat.
  • Retrofit - pembungkus untuk klien http tingkat rendah (okhttp). Klien otomatis dibuat berdasarkan potongan antarmuka yang mirip dengan beberapa ekstensi Jersey dan CXF.
  • Wraper volley untuk klien jdk http, oleh google
  • google-http wrapper untuk klien http jdk, atau apache httpcomponents, oleh google
  • Pembungkus unirest untuk klien http jdk, oleh kong
  • Pembungkus JakartaEE Resteasy untuk klien http jdk, oleh jboss, bagian dari kerangka jboss
  • jcabi-http wrapper untuk apache httpcomponents, bagian dari koleksi jcabi
  • Restlet wrapper untuk apache httpcomponents, bagian dari kerangka Restlet
  • pembungkus yang terjamin dengan konfirmasi untuk pengujian yang mudah

Peringatan tentang memilih klien HTTP / REST. Pastikan untuk memeriksa apa yang digunakan kerangka kerja Anda untuk klien HTTP, bagaimana cara kerjanya threading, dan idealnya gunakan klien yang sama jika ia menawarkannya. Itu jika Anda menggunakan sesuatu seperti Vert.x atau Play, Anda mungkin ingin mencoba menggunakan klien pendukungnya untuk berpartisipasi dalam apa pun bus atau loop reaktor yang disediakan kerangka kerja ... jika tidak bersiaplah untuk kemungkinan masalah threading yang menarik.

Adam Gent
sumber
1
Sayangnya klien Jersey tidak mendukung metode PATCH jika digunakan dengan JDK <8
botchniaque
3
Unirest sangat mudah digunakan tetapi desain statisnya membuatnya tidak dapat digunakan di lingkungan bersama dan server.
bekce
9
Mengenai unirest komentar, saya ingin menambahkan bahwa saat (akhir 2016) tampak seolah-olah proyek ini tidak lagi dipertahankan. Bahkan ada masalah terbuka yang meminta pengelola baru.
wegenmic
4
Bagi mereka yang suka Unirest , saya punya garpu yang saat ini sedang dipelihara / diperbarui secara aktif.
Josh
3
alangkah baiknya untuk mengubah jawaban menjadi komunitas wiki
tkruse
71

Seperti yang saya sebutkan di utas ini saya cenderung menggunakan Jersey yang mengimplementasikan JAX-RS dan dilengkapi dengan klien REST yang bagus. Yang menyenangkan adalah jika Anda mengimplementasikan sumber daya tenang Anda menggunakan JAX-RS maka klien Jersey dapat menggunakan kembali penyedia entitas seperti untuk JAXB / XML / JSON / Atom dan sebagainya - sehingga Anda dapat menggunakan kembali objek yang sama di sisi server seperti Anda gunakan pada tes unit sisi klien.

Sebagai contoh di sini adalah kasus uji unit dari proyek Apache Camel yang mencari muatan XML dari sumber daya tenang (menggunakan titik akhir objek JAXB). Metode resource (uri) didefinisikan dalam kelas dasar ini yang hanya menggunakan API klien Jersey.

misalnya

    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 Saya berharap bahwa versi masa depan JAX-RS menambahkan API sisi klien yang bagus di sepanjang garis yang ada di Jersey

James Strachan
sumber
Apakah ada metode di mana kita dapat menyebutkan daftar server layanan REST di ClientResource, jika server sedang down coba server berikutnya?
Njax3SmmM2x2a0Zf7Hpd
1
Hanya pembaruan, tetapi untuk menanggapi komentar James '' BTW ', versi baru JAX-RS 2.0 akan memiliki API sisi klien: infoq.com/presentations/Java-REST
Nick Klauer
64

Anda dapat menggunakan API Java SE standar:

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

Atau Anda dapat menggunakan API klien REST yang disediakan oleh implementasi JAX-RS seperti Jersey. API ini lebih mudah digunakan, tetapi membutuhkan stoples tambahan di jalur kelas Anda.

WebResource resource = client.resource("http://www.example.com/customers"); 
ClientResponse response = resource.type("application/xml");).put(ClientResponse.class, "<customer>...</customer."); 
System.out.println(response); 

Untuk informasi lebih lanjut, lihat:

bdoughan
sumber
15
13 baris untuk panggilan istirahat sederhana, pada 2018 , terdengar seperti terlalu banyak ...
Clint Eastwood
1
Setelah Anda menambahkan penanganan kesalahan dan opsi, itu tidak terlalu berbeda. Jika pendekatan SE terlihat lama, Anda selalu dapat membungkusnya dalam kelas ...:> Setelah dua hari men-debug konflik perpustakaan JAX-RS saya benar-benar baik-baik saja dengan 5 baris kode tambahan untuk menghindari seluruh mimpi buruk SPI.
tekHedd
2
@ClintEastwood posting ini ditulis pada tahun 2010
0ddlyoko
12

Jika Anda hanya ingin meminta layanan REST dan mengurai respons, Anda dapat mencoba Istirahat Tertanggung

// 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]");
Johan
sumber
9

Anda juga dapat memeriksa Restlet yang memiliki kemampuan sisi klien penuh, lebih berorientasi REST yang perpustakaan tingkat rendah seperti HttpURLConnection atau Apache HTTP Client (yang dapat kita manfaatkan sebagai konektor).

Salam, Jerome Louvel

Jerome Louvel
sumber
2
Pada 2019-10-24, tautan memberikan pengembalian: 'Platform Restlet telah mencapai akhir masa pakainya.'
Hans Deragon
6

Anda bisa mencoba Rapa . Beri tahu kami tanggapan Anda tentang hal yang sama. Dan jangan ragu untuk mencatat masalah atau fitur yang diharapkan.

Jasper
sumber
1
Rapa memiliki antarmuka yang sangat bagus dan beberapa dependensi. Alternatif yang baik untuk RestSharp di dunia .NET.
sore
proyek terlihat mati
tkruse
6

Saya ingin menunjukkan 2 opsi lagi:

Ophir Radnitz
sumber
1
Restfulie terlihat mati
tkruse
5

Saya baru-baru ini mencoba Retrofit Library dari kotak, Ini hebat dan Anda dapat memanggil API sisanya dengan sangat mudah. Konfigurasi berbasis anotasi memungkinkan kita untuk menyingkirkan banyak pengkodean pelat ketel.

Yasitha Waduge
sumber
4

Saya menggunakan Apache HTTPClient untuk menangani semua sisi HTTP hal.

Saya menulis XML SAX parser untuk konten XML yang mem-parsing XML ke model objek Anda. Saya percaya bahwa Axis2 juga memperlihatkan metode Model XML -> (Axis 1 menyembunyikan bagian ini, mengganggu). Generator XML sangat sederhana.

Tidak butuh waktu lama untuk kode, dan cukup efisien, menurut saya.

Astaga
sumber
4
Menurut saya ini adalah cara terburuk untuk melakukan REST. Menangani serialisasi secara manual di Jawa adalah buang-buang waktu ketika Anda memiliki begitu banyak opsi seperti JAXB dan Jackson. Bahkan memuat seluruh dokumen dan menggunakan XPath sedikit lebih lambat daripada SAX dan tidak ada apa-apanya dibandingkan dengan mendapatkan XML (kecepatan jaringan).
Adam Gent
1
Saya setuju juga, dan saya menulis komentar asli. Saat itu saya memiliki keinginan untuk mengendalikan deserialisation, tetapi saat ini saya akan menggunakan Jackson dan kelas model yang beranotasi.
JeeBee
4

OkHttp ringan dan kuat jika dikombinasikan dengan Retrofit juga. Ini berfungsi baik untuk penggunaan Java umum maupun di 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);
}
Sam Edwards
sumber
3

Karena tidak ada yang disebutkan, inilah yang lain: Feign , yang digunakan oleh Spring Cloud .

Leon
sumber
2

Meskipun sederhana untuk membuat klien HTTP dan membuat reuest. Tetapi jika Anda ingin menggunakan beberapa klien yang dibuat secara otomatis, Anda dapat menggunakan WADL untuk menggambarkan dan menghasilkan kode.

Anda dapat menggunakan RestDescribe untuk menghasilkan dan mengkompilasi WSDL, Anda dapat menghasilkan klien di php, ruby, python, java dan C # menggunakan ini. Ini menghasilkan kode bersih dan ada perubahan yang baik bahwa Anda harus men-tweak sedikit setelah pembuatan kode, Anda dapat menemukan dokumentasi yang bagus dan pemikiran yang mendasari di balik alat di sini .

Ada beberapa alat WADL yang menarik dan bermanfaat yang disebutkan di wintermute.

GG.
sumber
1

Saya menulis perpustakaan yang memetakan antarmuka java ke layanan JSON REST jarak jauh:

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);
}
George Georgovassilis
sumber
0

Coba lihat di http-rest-client

https://github.com/g00dnatur3/http-rest-client

Ini adalah contoh sederhana:

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

Perpustakaan menangani serialisasi json dan mengikat untuk Anda.

Ini adalah contoh lain,

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

Dan satu contoh terakhir,

RestClient client = RestClient.builder().build();
String url = ...
Person person = client.get(url, null, Person.class); //no queryParams

Bersulang!

g00dnatur3
sumber
0

Contoh klien jersey Rest:
Menambahkan ketergantungan:

         <!-- 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>

ForGetMethod dan melewati dua parameter:

          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 melewati satu parameter dan Mendapatkan Jawaban dari Daftar:

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

Di Atas Itu Mengembalikan Daftar yang kami terima sebagai Daftar dan kemudian mengubahnya menjadi Json Array dan kemudian Json Array ke Daftar.

Jika Kirim Permintaan lewat Objek Json sebagai Parameter:

   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 "));
    }
abhishek ringsia
sumber
0

Saat ini saya menggunakan https://github.com/kevinsawicki/http-request Saya suka kesederhanaannya dan cara contoh ditampilkan, tetapi kebanyakan saya dijual ketika saya membaca:

Apa ketergantungannya?

Tidak ada Tujuan perpustakaan ini adalah menjadi kelas kelas tunggal dengan beberapa kelas statis dalam. Proyek pengujian memang membutuhkan Jetty untuk menguji permintaan terhadap implementasi server HTTP yang sebenarnya.

yang menyelesaikan beberapa masalah pada proyek java 1.6. Adapun decoding json menjadi objek gson hanya tak terkalahkan :)

Edoardo
sumber
1
proyek terlihat mati, tidak ada komitmen sejak 2015.
tkruse