2015-01-02 2 views
6

У меня есть два приложения: один называется бар, что дает мне ресурсы в формате HAL. Другой - bcm, чтобы использовать эту услугу.Потребление весны Hateoas Restservice с RestTemplate

Пример ответа бар выглядит следующим образом:

[ 
    { 
     "name":"Brenner/in", 
     "_links":{ 
      "self":{ 
       "href":"..host/bbsng-app-rest/betrieb/15" 
      } 
     } 
    }, 
    { 
     "name":"Dienstleistungshelfer/in HW", 
     "_links":{ 
      "self":{ 
       "href":"..host/bbsng-app-rest/betrieb/4" 
      } 
     } 
    }, 
    { 
     ... 

Сейчас я стараюсь потреблять, что с млрд куб с использованием Spring RestTemplate. Мое решение работает, но я не очень доволен этим решением, и я думаю, что есть более чистый способ.

Мой клиент-код потребляя RestService выглядит следующим образом:

@Autowired private RestTemplate template; 

@Override 
@SuppressWarnings("unchecked") 
public BerufListe findeAlleBerufe() { 
    final BerufListe berufListe = new BerufListe(); 

    final ResponseEntity<List> entity = template.getForEntity(LinkUtils.findBeruf(), List.class); 

    if (OK.equals(entity.getStatusCode())) { 
     final List<LinkedHashMap> body = entity.getBody(); 
     for (final LinkedHashMap map : body) { 
      final LinkedHashMap idMap = (LinkedHashMap) map.get("_links"); 
      String id = remove(String.valueOf(idMap.get("self")), "href="); 
      id = remove(id, "{"); 
      id = remove(id, "}"); 
      final String name = String.valueOf(map.get("name")); 
      final Beruf beruf = new Beruf(id, name); 
      berufListe.add(beruf); 
     } 
    } 

    return berufListe; 
} 

Есть несколько уродливого кода, как вы видите. Один из них заключается в том, что у меня нет никаких дженериков для моих коллекций. В другом случае, я получаю Resource_ID очень сложным, и я использую StringUtils.remove много раз, чтобы извлечь собственный URL-адрес.

Я уверен, что должен быть более удобный способ потребления HAL-Response весной.

Спасибо.

ответ

3

Посмотрите на Resource класс от spring-hateaos.

Он предоставляет методы для извлечения ссылок из ответа. Однако, поскольку RestTemplate требует, чтобы вы предоставляли класс как переменную, я не нашел другого способа, кроме создания подкласса нужного объекта и использования его для RestTemplate.

Вы код может выглядеть следующим образом:

public class BerufResource extends Resource<Beruf> { } 

BerufResource resource = template.getForEntity("http://example.at/berufe/1", BerufResource.class); 
Beruf beruf = resource.getContent(); 
// do something with the entity 

Если вы хотите, чтобы запросить полный список, вам нужно будет передать версию массива Вашего объекта к RestTemplate:

BerufResource[] resources = template.getForEntity("http://example.at/berufe", BerufResource[].class); 

List<BerufResource> berufResources = Arrays.asList(resources); 
for(BerufResource resource : berufResources) { 
    Beruf beruf = resource.getContent(); 
} 

К сожалению , мы не можем написать Resource<Beruf>.class, который побеждает всю цель универсального класса, так как нам нужно снова создать подкласс для каждого объекта. Причина этого - стирание стилей. Я где-то читал, что они планируют ввести общую поддержку RestTemplate, но я не знаю никаких подробностей.

адресация извлечения идентификатора из URL:

Я рекомендовал бы использовать другую модель на стороне клиента, и заменить тип поля идентификатора с строкой и сохранить весь URL в нем. Таким образом, вы можете легко восстановить весь объект, когда захотите, и не нужно самостоятельно создавать URL. В любом случае вам понадобится URL-адрес позже, если вы планируете отправлять POST-запросы в ваш API, поскольку spring-hateaos требует, чтобы вы отправили ссылку вместо идентификатора. Типичным POST-запрос может выглядеть следующим образом:

{ 
    "firstname": "Thomas", 
    "nachname": "Maier", 
    "profession": "http://example.at/professions/1" 
} 
+0

Любое обновление с последними выпусками для этого ответа? – Snekse

+0

К сожалению, нет. Но с тех пор я еще не много исследовал. –

+2

Вы можете использовать 'new ParameterizedTypeReference >() {}', чтобы избежать подкласса. – afaulconbridge

Смежные вопросы