Java REST-клиент без схемы

Цель

Java-клиент для Yahoo HotJobs Resumé Search REST API.

Фон

Я привык писать клиентов веб-сервиса для API SOAP, где wsimport генерирует заглушки прокси, и вы выключены и Бег. Но это API REST, который для меня новичок.

Подробнее

Прогресс

Я рассмотрел вопрос Клиент для клиентов на Java?, но в автоматизированных решениях предполагается, что вы предоставляете как сервер, так и клиент, JAXB, вызываемый на POJO для генерации схемы и REST API.

Использование Jersey (a JAX-RS), я смог выполнить ручной HTTP-запрос:

import com.sun.jersey.api.client.*;

...

ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);

WebResource webResource = client.resource("https://hj.yahooapis.com/v1/HJAuthTokens");
webResource.accept("application/xml");

// body is a hard-coded string, with replacements for the variable bits
String response = webResource.post(String.class, body);

// parse response into a org.w3c.dom.Document
// interface with Document via XPATH, or write my own POJO mappings

Ответ может выглядеть так:

<?xml version="1.0" encoding="utf-8"?>   
<Response>   
    <ResponseCode>0</ResponseCode>   
    <ResponseMessage>Login successful</ResponseMessage>
    <Token>NTlEMTdFNjk3Qjg4NUJBNDA3MkJFOTI3NzJEMTdDNDU7bG9jYWxob3N0LmVnbGJwLmNvcnAueWFob28uY29tO0pVNWpzRGRhN3VhSS4yQVRqRi4wWE5jTWl0RHVVYzQyX3luYWd1TjIxaGx6U0lhTXN3LS07NjY2MzM1OzIzNDY3NTsxMjA5MDE2OTE5OzZCM1RBMVNudHdLbl9VdFFKMFEydWctLQ==</Token>   
</Response>  

Или это может выглядеть так:

<?xml version="1.0" encoding="utf-8"?>   
<yahoo:error xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xml:lang="en-US">   
    <yahoo:description>description</yahoo:description>   
    <yahoo:detail>   
        <ErrorCode>errorCode</ErrorCode>   
    </yahoo:detail>   
</yahoo:error>  

Вопросы

  • Есть ли способ автоматически генерировать POJOs, который можно объединить или развязать без формальной схемы?
  • Должен ли я попытаться сгенерировать эти POJO вручную, JAXB аннотации?
  • Есть ли какой-нибудь инструмент, который я должен использовать, поэтому мне не нужно делать все это вручную?

Ответ 1

Интересно, что они предоставляют HTTP-URL как URI пространства имен для схемы, но на самом деле не сохраняют их схему там. Это может быть надзор с их стороны, что может быть исправлено в электронной почте или в списке обсуждений.

Один из подходов состоит в том, чтобы создать свою собственную схему, но это похоже на большую работу для небольшого возврата. Учитывая, насколько просты сообщения, интересно, вам даже понадобится POJO, чтобы их обернуть? Почему не просто обработчик, который извлекает данные, которые вам нужны, используя XPath?


Изменить: взрыв из прошлого, но я увидел комментарий, перечитал вопрос и понял, что первое предложение трудно понять. Итак, уточнение:

Одна очень хорошая привычка, если вы собираетесь публиковать общедоступную веб-службу, заключается в том, чтобы сделать ваш документ схемы доступным по тому же URL-адресу, который вы используете для URI пространства имен схемы, или, лучше, иметь этот URL-адрес ссылка на полную документацию (пространство имен W3C XSD само по себе является хорошим примером: http://www.w3.org/2001/XMLSchema).

Ответ 2

Я бы предложил написать beans вручную и только аннотировать аннотации JAXB, если вам нужно. Для большинства аксессуаров/мутаторов (getters/seters) вам не обязательно; по умолчанию рассматриваются все общедоступные bean аксессоры и поля, имя выводится с использованием соглашения bean, а по умолчанию используется использование элементов вместо атрибутов (поэтому атрибуты должны быть аннотированы).

В качестве альтернативы вы можете, конечно, написать схему вручную, сгенерировать beans с помощью JAXB, если вам нравится W3C Schema. И просто используйте результирующий код, а не схему для привязки данных.

Что касается POJO: это может быть очень просто. Что-то вроде:

@XmlRootElement("Response")
class Response {
  public int responseCode;
  public String responseMessage;
  public String token; // or perhaps byte[] works for automated base64?
}

и аналогично для других. Или, используйте геттеры/сеттеры, если они вам нравятся, и не возражайте против более многословия. Это только контейнеры данных, не нужно слишком причудливо.

И если вы должны автоматически определять тип содержимого, подумайте об использовании синтаксического анализатора Stax, чтобы узнать, что является корневым элементом, а затем привяжите его с помощью JAXB Unmarshaller, передав XMLStreamReader, который указывает на этот корневой элемент. Таким образом вы можете передать другой тип объекта для привязки.

И наконец: запросы на отправку/получение: обычное старое HttpURLConnection работает нормально для запросов GET и POST (постройте, используя, скажем, URL.openConnection()). Jakarta HttpClient имеет больше возможностей, если это необходимо. Поэтому часто вам не нужен отдельный клиент REST - они могут пригодиться, но, как правило, основываются на простых частях http-клиента.

Ответ 3

Я нахожу HTTP4E очень полезным для создания вызовов REST. Это потрясающий плагин Eclipse, он имеет вкладки, раскраску синтаксиса, автоматическое предложение, генерацию кода, повторение вызова REST HTTP и т.д. Он отлично справляется с отладкой HTTP, подделкой HTTP, взломом. Мне так весело с ним.

http://www.ywebb.com/

Ответ 4

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

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

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