简体   繁体   中英

How to consume Spring HATEOAS REST resources containing links to another resources?

I have /studentCourses endpoint on the server (built with Spring Data REST) which returns the following content:

{
  "_embedded" : {
    "studentCourses" : [
      {
        "uid" : "5f23abe9-b24e-4e76-86b0-d539950a0a41",
        "registrationDate" : "7/23/2016",
        "_links" : {
          "self" : {
            "href" : "http://localhost:8080/studentCourses/5f23abe9-b24e-4e76-86b0-d539950a0a41"
          },
          "studentCourse" : {
            "href" : "http://localhost:8080/studentCourses/5f23abe9-b24e-4e76-86b0-d539950a0a41"
          },
          "course" : {
            "href" : "http://localhost:8080/studentCourses/5f23abe9-b24e-4e76-86b0-d539950a0a41/course"
          },
          "student" : {
            "href" : "http://localhost:8080/studentCourses/5f23abe9-b24e-4e76-86b0-d539950a0a41/student"
          }
        }
      },
      {
        ...
      },
      ...
    ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/studentCourses"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/studentCourses"
    }
  },
  "page" : {
    ...
  }
}

And the following client code:

class StudentCourseDTO {

    String uuid;

    String registrationDate;

    StudentDTO student; // contains uuid, firstName, lastName, etc.

    CourseDTO course; // contains uuid, name, etc.

    // getters, setters

}

RestTemplate restTemplate() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new Jackson2HalModule());
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    MappingJackson2HttpMessageConverter messageConverter =
            new MappingJackson2HttpMessageConverter();
    messageConverter.setObjectMapper(objectMapper);
    messageConverter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON));
    return new RestTemplate(Arrays.asList(messageConverter));
}

...

Collection<StudentCourseDTO> studentCourses = restTemplate().exchange(
        "http://localhost:8080/studentCourses",
        HttpMethod.GET, null,
        new ParameterizedTypeReference<PagedResources<StudentCourseDTO>>() {})
        .getBody().getContent();

The problem is that StudentCourseDTO.student and StudentCourseDTO.course are always null , but StudentCourseDTO.uuid and StudentCourseDTO.registrationDate are retrieved correctly from the server.
Anyone has an idea what I have missed?
I think there must be someway to tell RestTemplate to automatically follow the links in the returned content like student and course in the example above, but I haven't found a way to do this.

Just because there are links that does not mean they are automatically followed.

I would change the StudentCourseDTO to:

class StudentCourseDTO {

    String uuid;

    String registrationDate;

}

And then you would deserialize the response to a

PagedResources<Resource<StudentCourseDTO>> studentCourses = restTemplate().exchange(
        "http://localhost:8080/studentCourses",
        HttpMethod.GET, null,
        new ParameterizedTypeReference<PagedResources<Resource<StudentCourseDTO>>>() {})
        .getBody().getContent();

For each Resource<StudentCourseDTO> you can then follow the links for student and course , eg by using the RestTemplate to retrieve the resources.

Of course this gives you two additional calls per response item - but the only way to avoid this is to change the service to embed this information in the list resource.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM