Как вы создаете REST-клиент для Java? [закрыто]

248

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

Как вы создаете Java RESTful клиенты? Используя HTTPConnection и ручной анализ результата? Или специализированные клиенты, например, для Джерси или Apache CXR?

Yaba
источник
Только что нашел Apache Wink в инкубаторе Apache. Может быть интересным проектом для создания REST серверов и клиентов.
Яба
2
проверить это: igorpolevoy.blogspot.com/2011/01/java-rest-with-ease.html спасибо игорь
иполевой
Проверьте [Отдых] ( code.google.com/p/resting ). Он обещает вызвать службы REST и создать список объектов из ответа XML / JSON / YAML за один шаг.
neel
Отдыхает имеет проблемы с запросами POST.
RyanBrady
2
Вы можете сделать это очень просто с помощью resteasy (от Jboss). Я написал сообщение в блоге о том, как разработать Java REST-клиент, если вы хотите руководство по началу работы. В любом случае, в Java есть сотни альтернатив.
Гвидо

Ответы:

205

Это старый вопрос (2008), поэтому вариантов сейчас намного больше, чем было тогда:

ОБНОВЛЕНИЯ (проекты все еще активны в 2020 году):

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

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

Адам Гент
источник
1
К сожалению, клиент Джерси не поддерживает метод PATCH, если используется с JDK <8
botchniaque
3
Unirest очень прост в использовании, но его статический дизайн делает его непригодным для использования в общих и серверных средах.
bekce
9
Что касается самого необычного комментария, я хотел бы добавить, что он в настоящее время (конец 2016 года) выглядит так, как будто этот проект больше не поддерживается. Существует даже проблема, которая требует нового сопровождающего.
Wegenmic
4
Для тех, кто любит Unirest , у меня есть его форк, который в настоящее время активно поддерживается / обновляется.
Джош
3
было бы неплохо превратить ответ в вики сообщества
tkruse
72

Как я уже упоминал в этой теме, я склонен использовать Jersey, который реализует JAX-RS и поставляется с хорошим REST-клиентом. Приятно то, что если вы реализуете свои ресурсы RESTful с использованием JAX-RS, тогда клиент Джерси может повторно использовать провайдеры сущностей, такие как JAXB / XML / JSON / Atom и т. Д., Чтобы вы могли повторно использовать те же объекты на стороне сервера, что и вы использовать на клиентской стороне модульного теста.

Например, вот пример модульного теста из проекта Apache Camel, который ищет полезные нагрузки XML из ресурса RESTful (используя конечные точки объекта JAXB). Метод resource (uri) определен в этом базовом классе, который просто использует клиентский API Джерси.

например

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

Кстати, я надеюсь, что в будущей версии JAX-RS будет добавлен приятный API на стороне клиента по аналогии с тем, что в Джерси

Джеймс Страчан
источник
Есть ли способ, где мы можем упомянуть список серверов службы REST в ClientResource, если сервер не работает, попробуйте следующий сервер?
Njax3SmmM2x2a0Zf7Hpd
1
Просто обновление, но чтобы ответить на комментарий Джеймса «BTW», новая версия JAX-RS 2.0 будет иметь клиентский API: infoq.com/presentations/Java-REST
Ник Клауэр
65

Вы можете использовать стандартные API Java 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, такими как Джерси. Эти API-интерфейсы проще в использовании, но требуют дополнительных jar-файлов на пути вашего класса.

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

Для получения дополнительной информации см .:

bdoughan
источник
15
13 строк для простого отдыха, в 2018 году , звучит слишком много ...
Клинт Иствуд
1
После того, как вы добавите обработку ошибок и опции, они не будут существенно отличаться. Если подход SE кажется длинным, вы всегда можете заключить его в класс ...:> После двух дней отладки конфликтов библиотек JAX-RS у меня действительно все в порядке с 5 дополнительными строками кода, чтобы избежать всего кошмара SPI.
tekHedd
2
@ClintEastwood это сообщение было написано в 2010 году
0ddlyoko
13

Если вы хотите только вызвать службу REST и проанализировать ответ, вы можете попробовать Rest Assured

// 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
источник
Я нашел это более элегантным, чем многие другие предложенные решения.
Эрве Мутомбо
9

Вы также можете проверить Рестлет который обладает полными возможностями на стороне клиента, более ориентирован на REST, чем библиотеки более низкого уровня, такие как HttpURLConnection или Apache HTTP Client (которые мы можем использовать в качестве коннекторов).

С наилучшими пожеланиями, Джером Лувель

Джером Лувель
источник
2
По состоянию на 2019-10-24 гг. Указанная ссылка возвращает: «Платформа Restlet достигла конца срока службы».
Ханс Дерагон
6

Вы можете попробовать Rapa . Дайте нам знать ваши отзывы о том же. И не стесняйтесь регистрировать проблемы или ожидаемые функции.

Джаспер
источник
1
У Rapa действительно хороший интерфейс и несколько зависимостей. Хорошая альтернатива RestSharp в мире .NET.
второй половине дня
Проект выглядит мертвым
tkruse
6

Я хотел бы отметить еще 2 варианта:

Офир Радниц
источник
1
Restfulie выглядит мертвым
tkruse
6

Попробуйте JdkRequestиз jcabi-http (я разработчик). Вот как это работает:

String body = new JdkRequest("http://www.google.com")
  .header("User-Agent", "it's me")
  .fetch()
  .body()

Проверьте этот блог для получения более подробной информации: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

yegor256
источник
5

Я недавно попробовал Retrofit Library с квадрата, это здорово, и вы можете легко вызывать API отдыха. Конфигурация на основе аннотаций позволяет нам избавиться от большого количества кодировки котельной плиты.

Ясита Вадуге
источник
4

Я использую Apache HTTPClient для обработки всех аспектов HTTP.

Я пишу синтаксические анализаторы XML SAX для содержимого XML, которое анализирует XML в вашей объектной модели. Я считаю, что Axis2 также предоставляет методы XML -> Model (Axis 1, к сожалению, скрыл эту часть). Генераторы XML тривиально просты.

Кодирование не занимает много времени и, на мой взгляд, достаточно эффективно.

JeeBee
источник
4
На мой взгляд, это худший способ сделать REST. Ручная обработка сериализации в Java - пустая трата времени, когда у вас так много опций, как JAXB и Jackson. Даже загрузка всего документа и использование 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);
}
Сэм Эдвардс
источник
3

Поскольку никто не упомянул, вот еще один: Feign , который используется Spring Cloud .

Леон
источник
2

Хотя создать HTTP-клиента и выполнить его просто. Но если вы хотите использовать некоторые автоматически сгенерированные клиенты, вы можете использовать WADL для описания и генерации кода.

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

Есть несколько интересных и полезных инструментов WADL упомянутых на wintermute.

GG.
источник
1

Я написал библиотеку, которая отображает интерфейс Java на удаленную службу JSON REST:

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);
}
Георгий Георговасилис
источник
1

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

а. Джерси Отдых Клиента

б. Spring RestTemplate

с. Apache HTTP Client

Хари Кришна
источник
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

Ура!

g00dnatur3
источник
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, а затем массив Json в список.

Если после запроса отправить объект 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
Проект выглядит мертвым, без
коммитов