2016-06-14 61 views
9

sto cercando di invoque molto semplici webservices JSON che restituiscono dati di questo modulo:Deserialize JSON contenente (_links e _embedded) utilizzando primavera-hateoas

{ 
    "_embedded": { 
     "users": [{ 
      "identifier": "1", 
      "firstName": "John", 
      "lastName": "Doe", 
      "_links": { 
       "self": { 
        "href": "http://localhost:8080/test/users/1" 
       } 
      } 
     }, 
     { 
      "identifier": "2", 
      "firstName": "Paul", 
      "lastName": "Smith", 
      "_links": { 
       "self": { 
        "href": "http://localhost:8080/test/users/2" 
       } 
      } 
     }] 
    }, 
    "_links": { 
    "self": { 
     "href": "http://localhost:8080/test/users" 
    } 
    }, 
    "page": { 
    "size": 20, 
    "totalElements": 2, 
    "totalPages": 1, 
    "number": 0 
    } 
} 

Come si può vedere, è piuttosto semplice. Non ho problemi nell'analizzare i collegamenti, avendo i miei POJO estesi da ResourceSupport. Ecco quello che sembrano:

UsersJson (l'elemento radice)

public class UsersJson extends ResourceSupport { 
    private List<UserJson> users; 

    [... getters and setters ...] 
} 

UserJson

public class UserJson extends ResourceSupport { 

    private Long identifier; 

    private String firstName; 

    private String lastName; 

    [... getters and setters ...] 
} 

Il fatto è che mi aspettavo Jackson e la primavera di essere intelligente abbastanza per analizzare la proprietà _embedded e popolare il mio attributo UsersJson.users ma non lo è.

ho provato varie cose che ho trovato su internet, ma l'unica cosa che ho potuto ottenere un corretto funzionamento è stato quello di creare una nuova classe che agisce come un involucro _embedded:

UsersJson (l'elemento radice)

public class UsersJson extends ResourceSupport { 
    @JsonProperty("_embedded") 
    private UsersEmbeddedListJson embedded; 

    [... getters and setters ...] 
} 

embedded "wrapper" lavoro

public class UsersEmbeddedListJson extends ResourceSupport { 
    private List<UserJson> users; 

    [... getters and setters ...] 
} 

E ' s ma lo trovo abbastanza brutto.

Eppure se la seguente configurazione del RestTemplate avrebbe funzionato (soprattutto quando ho visto EmbeddedMapper in Jackson2HalModule), ma non ha:

 ObjectMapper mapper = new ObjectMapper(); 
     mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
     mapper.registerModule(new Jackson2HalModule()); 

     MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 
     converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json")); 
     converter.setObjectMapper(mapper); 

     RestTemplate restTemplate = new RestTemplate(Collections.singletonList(converter)); 

     ResponseEntity<UsersJson> result = restTemplate.getForEntity("http://localhost:8089/test/users", UsersJson.class, new HashMap<String, Object>()); 
     System.out.println(result); 

Qualcuno può dirmi che cosa mi manca?

+0

Non sembra che Jackson supporti i collegamenti HAL _embedded per impostazione predefinita. Il tuo involucro sembra un buon approccio. Vale anche la pena dare un'occhiata all'annotazione [Spring-HATEOAS @EnableHypermediaSupport] (http://docs.spring.io/spring-hateoas/docs/current/reference/html/#configuration.at-enable), ma io non l'ho usato, quindi non so se sarà utile. –

risposta

3

Infine, ho trovato un modo migliore per utilizzare le API application/hal + json.

Spring hateoas fornisce in realtà un client quasi pronto per l'uso: org.springframework.hateoas.client.Traverson.

Traverson traverson = new Traverson(new URI("http://localhost:8080/test"), MediaTypes.HAL_JSON); 
TraversalBuilder tb = this.restTemplate.follow("users"); 
ParameterizedTypeReference<Resources<UserJson>> typeRefDevices = new ParameterizedTypeReference<Resources<UserJson>>() {}; 
Resources<UserJson> resUsers = tb.toObject(typeRefDevices); 
Collection<UserJson> users= resUsers .getContent(); 

Come potete vedere, ho avuto UsersJson RID e UsersEmbeddedListJson.

Qui ci sono le dipendenze Maven ho aggiunto

<dependency> 
     <groupId>org.springframework.hateoas</groupId> 
     <artifactId>spring-hateoas</artifactId> 
     <version>0.19.0.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.plugin</groupId> 
     <artifactId>spring-plugin-core</artifactId> 
     <version>1.2.0.RELEASE</version> 
    </dependency> 
    <dependency> 
     <groupId>com.jayway.jsonpath</groupId> 
     <artifactId>json-path</artifactId> 
     <version>2.0.0</version> 
    </dependency> 
+0

Sto affrontando lo stesso problema di te. Quando ho provato il tuo suggerimento di usare 'restTemplate.follow (" users ")' allora ricevo un errore come "Il collegamento previsto è in arrivo con rel 'utenti' in risposta'. In un certo senso questo errore ha senso come 'follow' api presumo si aspetti che indichi qualche URL ma in questo caso non lo è. Non sono sicuro se ho fatto qualcosa di sbagliato qui – tabiul

0

dovuto aggiungere questo al mio DTO:

@JsonProperty("_links") 
public void setLinks(final Map<String, Link> links) { 
    links.forEach((label, link) -> add(link.withRel(label))); 
} 

dal ResourceSupport non ha standard di POJO/JSON-segnalato setter/costruttore per i collegamenti