Java için bir REST istemcisi nasıl oluşturulur? [kapalı]


248

JSR 311 ve uygulamaları ile Java nesnelerini REST yoluyla göstermek için güçlü bir standarda sahibiz. Ancak istemci tarafında, SOAP için Apache Axis ile karşılaştırılabilir bir şey eksik görünüyor - web hizmetini gizleyen ve verileri şeffaf bir şekilde Java nesnelerine geri döndüren bir şey.

Java RESTful istemcilerini nasıl oluşturursunuz? HTTPConnection ve sonucu manuel olarak ayrıştırma mı kullanıyorsunuz? Veya Jersey veya Apache CXR için özel müşteriler mi?


Hemen bulundu Apache Wink Apache enkubatörde. REST sunucuları ve istemcileri oluşturmak için ilginç bir proje olabilir.
Yaba


[Dinleniyor] 'a göz atın ( code.google.com/p/resting ). REST hizmetlerini çağırmayı ve tek adımda XML / JSON / YAML yanıtından nesne listesi oluşturmayı vaat ediyor.
neel

Dinlenmenin POST istekleriyle ilgili sorunları var.
RyanBrady

2
Huzursuzluk ile çok basit bir şekilde yapabilirsiniz (Jboss tarafından). Başlangıç kılavuzu istiyorsanız Java REST istemcisinin nasıl geliştirileceği hakkında bir blog yazısı yazdım . Her neyse, Java'da yüzlerce alternatif var.
Guido

Yanıtlar:


205

Bu eski bir soru (2008), bu yüzden şimdi o zamankinden çok daha fazla seçenek var:

GÜNCELLEMELER (2020'de halen aktif olan projeler):

  • Apache HTTP Bileşenleri (4.2) Akıcı bağdaştırıcı - Bu listedeki diğer birkaç aday tarafından kullanılan JDK için temel değiştirme. Eski Commons HTTP İstemcisi 3'ten daha iyi ve kendi REST istemcinizi oluşturmak için kullanımı daha kolay. JSON ayrıştırma desteği için Jackson gibi bir şey kullanmanız gerekecekveJersey / JAX-RS Rest istemcisine benzer kaynak URI'leri oluşturmak için HTTP bileşenleri URIBuilder'ı kullanabilirsiniz. HTTP bileşenleri de NIO'yu destekler, ancak REST'in kısa istek adı verildiğinde BIO'dan daha iyi performans alacağınızdan şüpheliyim. Apache HttpComponents 5 HTTP / 2 desteğine sahiptir.
  • OkHttp - Bu listedeki diğer birkaç aday tarafından kullanılan, http bileşenlerine benzer şekilde JDK için temel değiştirme. Daha yeni HTTP protokollerini (SPDY ve HTTP2) destekler. Android'de çalışır. Ne yazık ki gerçek bir reaktör döngüsü tabanlı asenkron seçeneği sunmuyor (bkz. Yukarıdaki Ning ve HTTP bileşenleri). Ancak, daha yeni HTTP2 protokolünü kullanırsanız bu sorun daha azdır (bağlantı sayısının sorun olduğu varsayılarak).
  • Ning Async-http-istemcisi - NIO desteği sağlar. Daha önce Sonatype tarafından Async-http-client olarak biliniyordu .
  • Feign alt düzeyi http müşteriler için sargı (okhttp apache HttpComponents). Bazı Jersey ve CXF uzantılarına benzer arayüz saplamalarına dayanan istemcileri otomatik olarak oluşturur. Güçlü yay entegrasyonu.
  • Sonradan yükseltme - alt düzey http istemcileri için sarıcı (okhttp). Bazı Jersey ve CXF uzantılarına benzer arayüz saplamalarına dayanan istemcileri otomatik olarak oluşturur.
  • Volley google tarafından jdk http müşteri için sarıcı,
  • jdk http istemcisi için google-http sarmalayıcısı veya Google tarafından apache http bileşenleri
  • JDK http istemcisi için Unirest sarıcı, Kong tarafından
  • JDK http istemcisi için Resteasy JakartaEE sarmalayıcısı, jboss tarafından, jboss çerçevesinin bir parçası
  • apache httpcomponents için jcabi-http sarmalayıcı, jcabi koleksiyonunun bir parçası
  • apache httpcomponents için restlet wrapper, restlet framework'ün parçası
  • kolay test için destekli güvenli sargı

HTTP / REST istemcilerini seçme konusunda bir uyarı. Çerçeve yığınınızın bir HTTP istemcisi için ne kullandığını, nasıl iş parçacığı oluşturduğunu kontrol ettiğinizden emin olun ve varsa aynı istemciyi kullanın. Vert.x veya Play gibi bir şey kullanıyorsanız, çerçevenin sağladığı herhangi bir veriyolu veya reaktör döngüsüne katılmak için destek istemcisini kullanmaya çalışabilirsiniz ...


1
Ne yazık ki Jersey istemcisi JDK <8 ile kullanıldığında PATCH yöntemini desteklemiyor
botchniaque

3
Unirest'in kullanımı çok kolaydır, ancak statik tasarımı onu paylaşılan ve sunucu ortamlarında kullanılamaz hale getirir.
bekce

9
En saf olmayan yorum ile ilgili olarak, şu anda (2016 sonu) bu projenin artık devam etmemiş gibi göründüğünü eklemek istiyorum. Yeni bir koruyucu isteyen bir sorun bile var .
wegenmic

4
Gibi olanlar için Unirest , ben var çatal şu anda aktif olarak / muhafaza güncellenen ediliyor bunun.
Josh

3
cevabı topluluk wiki'sine çevirmek güzel olur
tkruse

72

Ben de belirtildiği gibi bu konuya ben kullanma eğiliminde Jersey hangi uygular JAX-RS ve güzel DİNLENME istemcisi ile birlikte gelir. Güzel bir şey, RESTful kaynaklarınızı JAX-RS kullanarak uygularsanız Jersey istemcisi JAXB / XML / JSON / Atom gibi varlık sağlayıcılarını yeniden kullanabilir - böylece sunucu tarafında aynı nesneleri yeniden kullanabilirsiniz istemci tarafı birim testinde kullanın.

Örneğin , Apache Camel projesinden , RESTful kaynağından (JAXB nesnesi Uç Noktalarını kullanarak) XML yüklerini arayan bir birim test durumu . Kaynak (uri) yöntemi, yalnızca Jersey istemci API'sını kullanan bu temel sınıfta tanımlanır .

Örneğin

    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 Umarım JAX-RS'nin gelecek sürümü Jersey'deki satır boyunca güzel bir istemci tarafı API ekler


İstemciResource'ta REST hizmeti sunucu listesinden bahsedebileceğimiz bir yöntem var mı, sunucunun kapalı olması durumunda bir sonraki sunucuyu deneyin?
Njax3SmmM2x2a0Zf7Hpd

1
Sadece bir güncelleme, ancak James '' BTW 'yorumuna hitap etmek için, JAX-RS 2.0'ın yeni sürümü bir istemci tarafı API'sine sahip olacak: infoq.com/presentations/Java-REST
Nick Klauer

65

Standart Java SE API'lerini kullanabilirsiniz:

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

Veya Jersey gibi JAX-RS uygulamaları tarafından sağlanan REST istemci API'lerini kullanabilirsiniz. Bu API'lerin kullanımı daha kolaydır, ancak sınıf yolunuzda ek kavanozlar gerekir.

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

Daha fazla bilgi için, bkz:


15
Basit bir dinlenme çağrısı için 13 hat, 2018'de çok fazla gibi geliyor ...
Clint Eastwood

1
Hata işleme ve seçenekler ekledikten sonra, gerçekten önemli ölçüde farklı değildir. SE yaklaşımı uzun görünüyorsa, bunu her zaman bir sınıfa sarabilirsiniz ...:> JAX-RS kütüphane çakışmalarının hatalarını ayıkladıktan iki gün sonra, tüm SPI kabusundan kaçınmak için 5 ekstra kod satırıyla gerçekten iyiyim.
tekHedd

2
@ClintEastwood bu yazı 2010 yılında
yazılmıştır

13

Yalnızca bir REST hizmetini çağırmak ve yanıtı ayrıştırmak istiyorsanız, Güvenceye Alınmayı deneyebilirsiniz

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

Bunu önerilen diğer çözümlerin çoğundan daha zarif buldum.
Herve Mutombo

9

HttpURLConnection veya Apache HTTP İstemcisi (bağlayıcı olarak kaldırabileceğimiz) gibi alt düzey kitaplıklardan daha fazla REST odaklı tam istemci tarafı özelliklerine sahip Restlet'i de kontrol edebilirsiniz.

Saygılarımla, Jerome Louvel


2
2019-10-24 itibariyle, sağlanan bağlantı şu şekilde dönüyor: 'Restlet Platform kullanım ömrünün sonuna geldi.'
Hans Deragon

6

Rapa'yı deneyebilirsin . Bununla ilgili görüşlerinizi bize bildirin. Sorunları veya beklenen özellikleri günlüğe kaydetmekten çekinmeyin.


1
Rapa'nın gerçekten hoş bir arayüzü ve birkaç bağımlılığı var. .NET dünyasında RestSharp'a iyi bir alternatif.
öğleden sonra

projesi ölü görünüyor
tkruse



5

Son zamanlarda meydandan Retrofit Kütüphanesi denedim , Harika ve dinlenme API'nızı çok kolayca arayabilirsiniz. Ek açıklamaya dayalı yapılandırma, çok sayıda kazan plakası kodlamasından kurtulmamızı sağlar.


4

Ben şeylerin tüm HTTP tarafı işlemek için Apache HTTPClient kullanın.

XML'i nesne modelinize ayrıştıran XML içeriği için XML SAX ayrıştırıcıları yazıyorum. Axis2'nin XML -> Model yöntemlerini de ortaya çıkardığına inanıyorum (Axis 1 bu kısmı can sıkıcı bir şekilde sakladı). XML üreteçleri son derece basittir.

Bence kodlanması uzun sürmüyor ve oldukça verimli.


4
Bence bu REST yapmanın en kötü yolu. Java'da serileştirmeyi elle işlemek, JAXB ve Jackson gibi birçok seçeneğiniz olduğunda zaman kaybıdır. Belgenin tamamını yüklemek ve XPath kullanmak bile SAX'tan biraz daha yavaştır ve XML (ağ hızı) elde etmekle karşılaştırıldığında hiçbir şey değildir.
Adam Gent

1
Ben de katılıyorum ve orijinal yorumu yazdım. O zamanlar serileştirmeyi kontrol etme arzum vardı, ama bugünlerde Jackson ve terbiyeli açıklamalı model sınıfları kullanacaktım.
JeeBee

4

OkHttp, Retrofit ile birleştirildiğinde hafif ve güçlüdür. Bu, hem genel Java kullanımı hem de Android için iyi çalışır.

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

Sonradan yükseltme : http://square.github.io/retrofit/

public interface GitHubService {
  @GET("/users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}


2

Bir HTTP istemcisi oluşturmak ve bir reuest yapmak basit olsa da. Ancak, otomatik olarak oluşturulan bazı istemcilerden yararlanmak istiyorsanız, kodu tanımlamak ve oluşturmak için WADL'den yararlanabilirsiniz.

WSDL oluşturmak ve derlemek için RestDescribe kullanabilirsiniz , bunu kullanarak php, ruby, python, java ve C # istemcileri oluşturabilirsiniz. Temiz kod üretir ve kod oluşturulduktan sonra biraz ince ayar yapmanız gereken iyi bir değişiklik vardır, burada aracın arkasında iyi belgeler ve temel düşünceler bulabilirsiniz .

Kış mevsiminde bahsedilen ilginç ve kullanışlı birkaç WADL aracı vardır.




0

Http-rest-client'a bakmayı deneyin

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

İşte basit bir örnek:

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

Kütüphane sizin için json serileştirme ve ciltleme ile ilgilenir.

İşte başka bir örnek,

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

Ve son bir örnek,

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

Şerefe!


0

Jersey Rest istemcisi örnekleri:
Bağımlılık ekleme:

         <!-- 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 ve iki parametrenin iletilmesi:

          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 bir parametreyi geçirir ve Listeden Geri Alınır:

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

Yukarıda, Liste olarak kabul ettiğimiz ve daha sonra Json Array'a ve ardından Json Array'ı Listeye dönüştürdüğümüz bir Liste döndürür.

Post İsteği Json Nesnesini Parametre Olarak Geçiyorsa:

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

0

Şu anda https://github.com/kevinsawicki/http-request kullanıyorum Basitliklerini ve örneklerin gösterilmesini beğendim, ancak okuduğumda çoğunlukla satıldım:

Bağımlılıklar nelerdir?

Yok. Bu kütüphanenin amacı, bazı iç statik sınıfları olan tek bir sınıf sınıfı olmaktır. Sınama projesi, istekleri gerçek bir HTTP sunucusu uygulamasına karşı sınamak için Jetty gerektirir.

java 1.6 projesinde bazı sorunları çözdü. Json'u nesnelere çözmek için gson sadece yenilmez :)


1
projesi ölü görünüyor, 2015'ten beri taahhüt yok.
tkruse
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.