2015-01-02 16 views
6

Mam dwie aplikacje, jedna nazywa się bar, co zapewnia mi zasoby w formacie HAL. Druga to bcm do korzystania z tej usługi.Konsumpcja Spring Hateoas Restservice z RestTemplate

Przykład odpowiedzi pasku wygląda następująco:

[ 
    { 
     "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" 
      } 
     } 
    }, 
    { 
     ... 

Teraz staram się spożywać że od bcm wykorzystaniem Wiosna RestTemplate. Moje rozwiązanie działa, ale nie jestem zadowolony z tego rozwiązania i wydaje mi się, że jest bardziej czysty sposób.

Mój klient-Code spożywania RestService wygląda następująco:

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

Istnieje kilka brzydki kod, jak widać. Jednym z nich jest to, że nie mam generycznych dla moich kolekcji. Inną kwestią jest bardzo skomplikowane Resource_ID i używam StringUtils.remove wiele razy, aby wyodrębnić własny adres URL.

Jestem pewien, że musi istnieć wygodniejszy sposób spożywania odpowiedzi HAL na wiosnę.

Dzięki.

Odpowiedz

3

Spójrz na klasę Resource z wiosennych hateaos.

Udostępnia metody wyodrębniania linków z odpowiedzi. Jednak, ponieważ RestTemplate wymaga podania klasy jako zmiennej, nie znalazłem innej metody niż tworzenie podklasy pożądanego obiektu i użycie go dla RestTemplate. Kod

Mogłeś wtedy wyglądać następująco:

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 

Jeśli chcesz poprosić o pełną listę, trzeba by przejść wersję tablicy swojego podmiotu 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(); 
} 

Niestety , nie możemy napisać Resource<Beruf>.class, która pokonuje cały cel klasy generycznej, ponieważ musimy ponownie utworzyć podklasę dla każdej jednostki. Powodem tego jest wymazanie typu. Czytałem gdzieś, że planują wprowadzić ogólne wsparcie dla RestTemplate, ale nie jestem świadomy żadnych szczegółów.

Adresowanie ekstrakcję ID z adresem URL:

Polecam użyć innego modelu po stronie klienta i zastąpić typ pola id z ciągiem i przechowywać cały adres URL w nim. W ten sposób możesz łatwo ponownie pobrać cały encję, kiedy tylko chcesz i nie musisz samodzielnie tworzyć adresu URL. Będziesz potrzebował adresu URL później, jeśli planujesz wysyłać żądania POST do swojego interfejsu API, ponieważ wiosenne hateaos wymaga wysłania linku zamiast identyfikatora. Typowym POST-prośba mogłaby wyglądać następująco:

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

każdej aktualizacji z ostatnich wydań dla tej odpowiedzi? – Snekse

+0

Niestety nie. Ale od tego czasu również nie zrobiłem zbyt wielu badań. –

+2

Możesz użyć 'new ParameterizedTypeReference >() {}', aby uniknąć podklasy. – afaulconbridge

Powiązane problemy