2015-01-02 15 views
6

Ho due applicazioni, una si chiama bar, cosa mi fornisce le risorse in formato HAL. L'altro è bcm per consumare quel servizio.Consumare Spring Hateoas Restservice con RestTemplate

Esempio di risposta bar si presenta così:

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

Ora cerco di consumare che dal miliardi di metri cubi usando Primavera RestTemplate. La mia soluzione funziona, ma non sono felice con quella soluzione in qualche modo e immagino ci sia un modo più pulito.

mio client-Code che consumano RestService assomiglia:

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

ci sono poche codice di brutto, come si vede. Uno di questi è che non ho generici per le mie collezioni. L'altro punto, ho il Resource_ID molto complicato, e io uso StringUtils.remove molte volte per estrarre l'auto url.

Sono sicuro che ci deve essere un modo più conveniente per consumare HAL-Response entro la primavera.

Grazie.

risposta

3

Dai un'occhiata alla classe Resource da primavera-hateaos.

Fornisce metodi per estrarre i collegamenti dalla risposta. Tuttavia, come RestTemplate richiede di fornire la classe come variabile, non ho trovato un modo diverso se non creare una sottoclasse dell'entità desiderata e usarla per RestTemplate. Codice

Si potrebbe quindi simile a questa:

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 

Se si desidera richiedere un elenco completo, si avrebbe bisogno di passare la versione matrice di vostra entità a 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(); 
} 

Purtroppo , non possiamo scrivere Resource<Beruf>.class che vanifica l'intero scopo della classe generica, poiché è necessario creare nuovamente una sottoclasse per ogni entità. La ragione di ciò si chiama cancellazione di tipo. Ho letto da qualche parte che stanno progettando di introdurre il supporto generico per RestTemplate ma non sono a conoscenza di alcun dettaglio.

Affrontare l'estrazione del id dall'URL:

mi sento di raccomandare di utilizzare un diverso modello sul lato client e sostituire il tipo di campo ID con lo spago e memorizzare l'intero URL in esso. In questo modo, puoi facilmente rimettere a posto l'intera entità in qualsiasi momento e non hai bisogno di costruire l'URL tu stesso. Avrai comunque bisogno dell'URL in un secondo momento, se prevedi di inviare richieste POST alla tua API, poiché spring-hateaos ti richiede di inviare il link al posto dell'ID. Un tipico POST-richiesta potrebbe essere la seguente:

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

Qualsiasi aggiornamento con le recenti versioni di questa risposta? – Snekse

+0

Purtroppo no. Ma da allora non ho fatto molte ricerche. –

+2

È possibile utilizzare 'new ParameterizedTypeReference >() {}' per evitare la sottoclasse. – afaulconbridge

Problemi correlati