Вопрос
Благодаря JSR 311 и его реализациям у нас есть мощный стандарт для предоставления объектов Java через REST.Однако на стороне клиента, похоже, не хватает чего-то, что можно сравнить с Apache Axis для SOAP - чего-то, что скрывает веб-сервис и прозрачно упорядочивает данные обратно в объекты Java.
Как вы создаете клиенты Java RESTful?Использование HTTPConnection и ручной анализ результата?Или специализированные клиенты, например.Джерси или Apache CXR?
Решение
Это старый вопрос (2008 г.), поэтому сейчас существует гораздо больше вариантов, чем было тогда:
- Апач CXF имеет три разных Параметры REST-клиента
- Джерси (упомянутое выше).
- Весна также есть свое название RestTemplate
- Общий HTTP-клиент создайте свой собственный для старых проектов Java.
ОБНОВЛЯТЬ примерно 2014 год:
Асинхронный http-клиент от Sonatype. Ning Async-http-клиент.
Новинка в блоке, обеспечивающая поддержку NIO (хотя, честно говоря, я не думаю, что это действительно повышает производительность клиентов так, как серверы).
- HTTP-компоненты Apache (4.2) Fluent-адаптер - Лучше, чем старый HTTP-клиент Commons 3, и его проще использовать для создания собственного REST-клиента.Вам придется использовать что-то вроде Джексону за анализ JSON поддержку и вы можете использовать HTTP-компоненты URIBuilder для создания URI ресурсов. аналогично клиенту Jersey/JAX-RS Rest.Компоненты HTTP также поддерживают NIO, но я сомневаюсь, что вы получите лучшую производительность, чем BIO, учитывая природу коротких запросов REST.
ОБНОВЛЕНИЕ 2016 ГОДА:
- ОкHttp - Поддерживает новые протоколы HTTP (SPDY и HTTP2).Работает на Андроиде.К сожалению, он не предлагает настоящую асинхронную опцию на основе реакторного цикла (см. выше компоненты Ning и HTTP).Однако если вы используете более новый протокол HTTP2, это не проблема (при условии, что количество подключений является проблемой).
- Модернизация - Будет автоматически создаваться клиенты на основе заглушек интерфейса, подобных некоторым расширениям Jersey и CXF.Использует OkHttp.
- Apache HttpComponents 5 предположительно будет иметь поддержку HTTP2.
Предостережение относительно выбора клиентов HTTP/REST.Обязательно проверьте, какой стек вашей платформы использует для HTTP-клиента, как он выполняет многопоточность, и в идеале используйте тот же клиент, если он его предлагает.То есть, если вы используете что-то вроде Vert.x или Play, вы можете попробовать использовать его поддерживающий клиент для участия в любом цикле шины или реактора, который предоставляет платформа...в противном случае будьте готовы к возможным интересным проблемам с потоками.
Другие советы
Как я упоминал в эта тема Я склонен использовать Джерси который реализует JAX-RS и поставляется с хорошим клиентом REST.Приятно то, что если вы реализуете свои ресурсы RESTful с использованием JAX-RS, тогда клиент Джерси может повторно использовать поставщиков сущностей, таких как JAXB/XML/JSON/Atom и т. д., поэтому вы можете повторно использовать те же объекты на стороне сервера, что и вы. используйте модульный тест на стороне клиента.
Например вот пример модульного теста из Проект Apache Camel который ищет полезные данные XML из ресурса RESTful (с использованием конечных точек объекта JAXB).Метод ресурса(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, аналогичный API в Джерси.
Вы можете использовать стандартные 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, такими как Jersey.Эти 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);
Для получения дополнительной информации см.:
Если вы хотите только вызвать службу 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]");
Вы также можете проверить Restlet , который обладает полными возможностями на стороне клиента, более ориентирован на REST, чем библиотеки более низкого уровня, такие как как HttpURLConnection или Apache HTTP Client (который мы можем использовать как коннекторы).
С уважением, Джером Лувель
Вы можете попробовать Rapa . Дайте нам знать ваши отзывы о том же. И не стесняйтесь регистрировать проблемы или ожидаемые функции.
Я недавно попробовал Модифицировать библиотеку с нуля, это здорово, и вы можете вызывать API для отдыха очень легко. Конфигурация на основе аннотаций позволяет нам избавиться от большого количества кодировки котельной плиты.
Хочу отметить еще 2 варианта:
- Рестфули, основанный на веб-фреймворке VRaptor, имеет реализации как на стороне сервера, так и на стороне клиента с очень хорошей поддержкой Hypermedia.
- RESTEasy имеет Клиент на основе прокси-сервера JAX-RS выполнение.
Я использую Apache HTTPClient для обработки всех аспектов HTTP.
Я пишу синтаксические анализаторы XML SAX для содержимого XML, которое анализирует XML в вашей объектной модели. Я считаю, что Axis2 также предоставляет XML - > Модельные методы (Ось 1 скрывала эту часть, досадно). Генераторы XML тривиально просты.
Кодирование не занимает много времени, и, на мой взгляд, весьма эффективно.
OkHttp - легкий и мощный в сочетании с Retrofit. Это хорошо работает для общего использования Java, а также на Android.
Попробуйте 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 р>
Поскольку никто не упомянул, вот еще один: Feign , который используется Spring Cloud .
Уже некоторое время я использую Resty : р>
JSONResource jsonResource = new Resty (). json (uri);
Некоторые примеры можно найти здесь .
Хотя создать HTTP-клиент и выполнить его просто. Но если вы хотите использовать некоторые автоматически сгенерированные клиенты, вы можете использовать WADL для описания и генерации кода. Р>
Вы можете использовать RestDescribe для генерации и компиляции WSDL, вы можете генерировать клиентов в PHP, Ruby, Python, Java и C #, используя это. Он генерирует чистый код, и есть хорошее изменение: вам нужно немного его настроить после генерации кода, вы можете найти хорошую документацию и основные идеи этого инструмента здесь .
Существует несколько интересных и полезных инструментов WADL , упомянутых на wintermute. р>
Я написал библиотеку, которая отображает интерфейс 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);
}
Попробуйте посмотреть 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
Ваше здоровье!
Примеры клиентов Джерси Отдых:
Добавление зависимости:
<!-- 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 "));
}