2016-06-14 22 views
9

Ich versuche, sehr einfach json Web Service bereitgestellt invoque, die Daten dieser Form zurück:Deserialize JSON, die (_links und _embedded) mit feder 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 
    } 
} 

Wie Sie sehen können, ist es ziemlich geradlinig ist. Ich habe keine Probleme beim Parsen der Links, da meine POJOs von ResourceSupport erweitert werden. Hier ist, wie sie aussehen:

UsersJson (das Wurzelelement)

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 ...] 
} 

Die Sache ist, dass ich es erwartet hatte Jackson und Frühjahr klug zu sein genug, um die _embedded-Eigenschaft zu analysieren und mein UsersJson.users-Attribut aufzufüllen, tut dies aber nicht.

Ich habe versucht, verschiedene Dinge, die ich im Internet gefunden, aber das einzige, was ich war an der Arbeit konnte richtig eine neue Klasse, die als eine _embedded Wrapper zu erstellen:

UsersJson (das Wurzelelement)

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

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

Embedded "Wrapper"

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

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

Es Arbeit s, aber ich finde es ziemlich hässlich.

Doch ich aber die folgende Konfiguration des RestTemplate würde gearbeitet haben (vor allem, wenn ich sah, EmbeddedMapper in Jackson2HalModule), aber es hat nicht:

 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); 

Kann mir jemand sagen, was ich fehle?

+0

Es sieht nicht so aus, als ob Jackson HAL _ eingebettete Links standardmäßig unterstützt. Ihr Wrapper sieht nach einem guten Ansatz aus. Es lohnt sich auch, einen Blick auf die Annotation [Spring-HATEOAS @EnableHypermediaSupport] (http://docs.spring.io/spring-hateoas/docs/current/reference/html/#configuration.at-enable) zu werfen, aber ich habe es nicht benutzt, also weiß nicht, ob es nützlich sein wird. –

Antwort

3

Schließlich fand ich eine bessere Möglichkeit, diese Anwendung/Hal + Json APIs zu verbrauchen.

Spring hateoas bietet tatsächlich einen Client fast fertig zu verwenden: 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(); 

Wie Sie sehen können, habe ich loswerden UsersJson und UsersEmbeddedListJson.

Hier sind die Maven Abhängigkeiten I

hinzugefügt
<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

Ich stehe vor dem gleichen Problem wie du. Als ich Ihren Vorschlag, 'restTemplate.follow (" users ") zu verwenden, ausprobiert habe, bekomme ich einen Fehler wie' Erwarteter Link zu rel 'Benutzern' als Antwort zu finden '. In gewissem Sinne ist dieser Fehler sinnvoll, da 'follow' api davon ausgeht, dass er auf eine URL verweist, in diesem Fall jedoch nicht. Ich bin mir nicht sicher, ob ich hier etwas falsch gemacht habe – tabiul

0

Wäre dies meine DTO hinzuzufügen:

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

seit ResourceSupport keine POJO Standard/Json-signalisierte Setter/Konstruktor für Links hat