Як створити клієнт REST для Java? [зачинено]


248

З JSR 311 та його реалізаціями у нас є потужний стандарт викриття Java-об'єктів через REST. Однак, на стороні клієнта, здається, чогось не вистачає, що можна порівняти з Apache Axis для SOAP - те, що приховує веб-сервіс і марширує дані прозоро назад до об’єктів Java.

Як створювати клієнтів Java RESTful? Використовуючи HTTPConnection та ручний аналіз результату? Або спеціалізовані клієнти, наприклад, Jersey або Apache CXR?


Щойно знайшли підморгування Apache в інкубаторі Apache. Може бути цікавим проектом для створення REST-серверів та клієнтів.
Яба

2
перевірити це: igorpolevoy.blogspot.com/2011/01/java-rest-with-ease.html спасибі igor
ipolevoy

Перевірте [Відпочиває] ( code.google.com/p/resting ). Він обіцяє викликати послуги REST та створити список об’єктів із відповіді XML / JSON / YAML за один крок.
neel

У відпочинку є проблеми з POST-запитами.
RyanBrady

2
Ви можете зробити це дуже простим способом за допомогою resteasy (від Jboss). Я написав повідомлення в блозі про те, як розробити клієнт Java REST, якщо ви хочете посібник із початку роботи. У будь-якому випадку на Яві існують сотні альтернатив.
Гвідо

Відповіді:


205

Це старе запитання (2008), тож зараз є набагато більше варіантів, ніж тоді:

ОНОВЛЕННЯ (проекти, які все ще діють до 2020 року):

  • Apache HTTP Components (4.2) Вільний адаптер - Базова заміна JDK, використовувана кількома іншими кандидатами у цьому списку. Краще, ніж старий Commons HTTP-клієнт 3 і простіше використовувати для створення власного REST-клієнта. Вам потрібно буде використовувати щось на зразок Jackson для підтримки розбору JSON, і ви можете використовувати компоненти HTTP URIBuilder для побудови URI ресурсів, схожих на Jersey / JAX-RS Rest client. HTTP компоненти також підтримують NIO, але я сумніваюся, що ви отримаєте кращу продуктивність, ніж BIO, враховуючи короткий запит REST. Apache HttpComponents 5 має підтримку HTTP / 2.
  • OkHttp - Базова заміна JDK, подібна до компонентів http, яка використовується декількома іншими кандидатами у цьому списку. Підтримує новіші протоколи HTTP (SPDY і HTTP2). Працює на Android. На жаль, він не пропонує справжньої опції асинхронизації на основі реактора (див. Компоненти Ning та HTTP вище). Однак якщо ви використовуєте новіший протокол HTTP2, це менше проблеми (якщо вважати кількість підключень, це проблема).
  • Ning Async-http-client - забезпечує підтримку NIO. Раніше Sonatype називався клієнтом Async-http .
  • Призначте обгортку для клієнтів нижчого рівня http (okhttp, apache httpcomponents). Автоматично створює клієнтів на основі заглушок інтерфейсу, подібних до деяких розширень Джерсі та CXF. Сильна весняна інтеграція.
  • Модернізація - обгортка для клієнтів нижчого рівня http (okhttp). Автоматично створює клієнтів на основі заглушок інтерфейсу, подібних до деяких розширень Джерсі та CXF.
  • Волей обгортка для jdk http-клієнта, від Google
  • google-http обгортку для jdk http-клієнта або apache httpcomponents від Google
  • Unirest обгортка для jdk http-клієнта, від конг
  • Ретеаси JakartaEE для клієнта jdk http, від jboss, частина фреймворку jboss
  • jcabi-http для апаратних httpcomponents, частина колекції jcabi
  • резлетобгортка для для апаратних httpcomponents, частина рамки для рестлета
  • спокійні обгортка з твердженнями для легкого тестування

Застереження щодо вибору клієнтів HTTP / REST. Не забудьте перевірити, що ваш стек фреймворків використовує для HTTP-клієнта, як він виконує нарізку, і в ідеалі використовувати той же клієнт, якщо він пропонує. Тобто, якщо ви використовуєте щось подібне до Vert.x або Play, ви можете спробувати використати його резервного клієнта для участі у будь-якій шині або реакторному циклі, яку передбачає рамка ... в іншому випадку будьте готові до можливих цікавих проблем з нанизуванням.


1
На жаль, клієнт Джерсі не підтримує метод PATCH, якщо він використовується з JDK <8
botchniaque

3
Unirest дуже простий у використанні, але його статична конструкція робить його непридатним у спільних та серверних середовищах.
bekce

9
Щодо найцікавішого коментаря, я хочу додати, що він наразі (кінець 2016 року) виглядає так, ніби цей проект більше не підтримується. Існує навіть проблема, яка вимагає нового технічного обслуговування.
wegenmic

4
Для тих , хто любить Unirest , я отримав вилку з цього , що в даний час активно підтримуване / оновлюється.
Джош

3
було б добре перетворити відповідь у вікі спільноти
tkruse

72

Як я вже згадував у цій темі, я, як правило, використовую Джерсі який реалізує JAX-RS і постачається з хорошим клієнтом REST. Приємно, що якщо ви реалізуєте свої RESTful ресурси за допомогою JAX-RS, то клієнт Джерсі може повторно використовувати постачальників організацій, таких як JAXB / XML / JSON / Atom тощо, - таким чином ви можете повторно використовувати ті самі об’єкти на стороні сервера, що і ви використання на тесті клієнтської одиниці.

Наприклад, ось тестовий випадок з проекту Apache Camel, який шукає корисні навантаження XML з ресурсу RESTful (використовуючи Кінцеві точки об'єкта JAXB). Метод ресурсів (uri) визначений у цьому базовому класі який просто використовує клієнтський API Jersey.

напр

    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 Я сподіваюсь, що майбутня версія JAX-RS додасть приємний API на стороні клієнта відповідно до тієї, що в Джерсі


Чи існує метод, де ми можемо згадати список серверів сервісу REST у ClientResource, якщо сервер не працює, спробуйте наступний сервер?
Njax3SmmM2x2a0Zf7Hpd

1
Лише оновлення, але на адресу коментаря Джеймса "BTW", нова версія JAX-RS 2.0 матиме клієнтський API: infoq.com/presentations/Java-REST
Нік Клауер

65

Ви можете використовувати стандартні API SE SE:

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

Або ви можете використовувати API REST-клієнтів, що надаються реалізаціями JAX-RS, такими як Jersey. Ці API простіші у використанні, але потребують додаткових банок на шляху вашого класу.

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

Для отримання додаткової інформації див:


15
13 рядків для простого дзвінка на відпочинок у 2018 році , здається, занадто багато ...
Клінт Іствуд

1
Щойно ви додасте поводження з помилками та параметри, це насправді не суттєво відрізняється. Якщо підхід SE здається довгим, ви завжди зможете зафіксувати його у класі ...:> Після двох днів налагодження конфліктів бібліотеки JAX-RS мені дуже добре з 5 додатковими рядками коду, щоб уникнути цілого кошмару SPI.
tekHedd

2
@ClintEastwood ця публікація була написана в 2010 році
0ddlyoko

13

Якщо ви хочете лише запустити послугу REST та проаналізувати відповідь, можете спробувати Будьте впевнені

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

Я вважав це більш елегантним, ніж багато інших запропонованих рішень.
Ерве Мутомбо

9

Ви також можете перевірити Restlet який має всі можливості клієнта, більш орієнтовані на REST, що бібліотеки нижчого рівня, такі як HttpURLConnection або Apache HTTP-клієнт (які ми можемо використовувати як з'єднувачі).

З найкращими побажаннями, Джером Лувел


2
Станом на 2019-10-24 посилання надає посилання: "Платформа Restlet закінчилась."
Ганс Дерагон

6

Ви можете спробувати Рапу . Повідомте нам ваші відгуки про те саме. І сміливо записуйте проблеми або очікувані функції.


1
Рапа має дійсно приємний інтерфейс і мало залежностей. Хороша альтернатива RestSharp у світі .NET.
вдень

проект виглядає мертвим
tkruse



5

Нещодавно я спробував бібліотеку модернізації з площі, її чудово, і ви можете легко зателефонувати на ваш API API. Конфігурація на основі анотацій дозволяє позбутися багатьох кодуючих пластин котла.


4

Я використовую Apache HTTPClient для обробки всіх HTTP-речей.

Я записую XML SAX-парсери для вмісту XML, який аналізує XML у вашій об'єктній моделі. Я вважаю, що Axis2 також розкриває методи XML -> Model (Axis 1 приховував цю частину, дратівливо). Генератори XML тривіально прості.

Кодування не займе багато часу, і, на мій погляд, це досить ефективно.


4
На мою думку, це найгірший спосіб зробити REST. Ручне управління серіалізацією на Java - це марна трата часу, коли у вас є так багато варіантів, як JAXB та Джексон. Навіть завантаження всього документа та використання XPath дещо повільніше, ніж SAX, і ніщо в порівнянні з отриманням XML (швидкість мережі).
Адам Гент

1
Я теж згоден, і написав оригінальний коментар. Тоді у мене було бажання контролювати десеріалізацію, але в наш час я використовував би Джексона та гідно анотованих модельних класів.
JeeBee

4

OkHttp є легким і потужним у поєднанні з Retrofit. Це добре працює як для загального використання Java, так і для 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();
}

Модернізація : http://square.github.io/retrofit/

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


2

Хоча просто створити клієнт HTTP і зробити реест. Але якщо ви хочете скористатися деякими клієнтами, створеними автоматично, ви можете використовувати WADL для опису та створення коду.

Ви можете використовувати RestDescribe для створення та компіляції WSDL, ви можете генерувати клієнтів у php, ruby, python, java та C # за допомогою цього. Він генерує чистий код, і є хороші зміни, що вам доведеться трохи підправити його після створення коду, ви можете знайти хорошу документацію та основні думки за інструментом тут .

Є кілька цікавих і корисних інструментів WADL, згаданих на Wintermute.



1

Я використовував RestAssured більшу частину часу для розбору відповідей відпочинку та тестування послуг. Крім Rest Assured, я використовував бібліотеки нижче, щоб спілкуватися з Resful Services.

а. Клієнт відпочинку в Джерсі

б. Весняний шаблон відпочинку

c. HTTP-клієнт Apache


0

Спробуйте подивитися http-rest-client

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

Ось простий приклад:

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

Бібліотека піклується про серіалізацію json та прив’язку для вас.

Ось ще один приклад,

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

І останній приклад,

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

Ура!


0

Приклади джерсі Відпочиваючий клієнт:
Додавання залежності:

         <!-- 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 та передача двох параметрів:

          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 передає один параметр і отримує репозицію списку:

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

Вгорі він повертає список, який ми приймаємо як список, а потім перетворюємо його в Json Array, а потім Json Array у список.

Якщо опублікувати запит, передаючи об'єкт Json як параметр:

   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

Зараз я використовую https://github.com/kevinsawicki/http-request Мені подобається їхня простота та те, як показуються приклади, але в основному мене продали, коли я читав:

Які залежності?

Жоден. Мета цієї бібліотеки - бути класом єдиного класу з деякими внутрішніми статичними класами. Тестовий проект вимагає Jetty для тестування запитів на фактичну реалізацію HTTP-сервера.

який розібрав деякі проблеми в проекті java 1.6. Щодо розшифровки json в об’єкти gson просто непереможний :)


1
проект виглядає мертвим, жодних зобов’язань з 2015 року.
tkruse
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.