如何使用包含指向其他资源的链接的Spring HATEOAS REST资源?

时间:2016-08-08 15:54:43

标签: java spring jackson spring-data-rest spring-hateoas

我在服务器上有/studentCourses端点(使用Spring Data REST构建),它返回以下内容:

{
  "_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" : {
    ...
  }
}

以下客户端代码:

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

问题是StudentCourseDTO.studentStudentCourseDTO.course始终是null,但是StudentCourseDTO.uuidStudentCourseDTO.registrationDate是从服务器正确检索的。
任何人都知道我错过了什么? 我认为必须要告诉RestTemplate自动关注返回内容中的链接,例如上面示例中的studentcourse,但我还没有找到办法这样做。

1 个答案:

答案 0 :(得分:0)

仅仅因为有链接并不意味着它们会被自动跟踪。

我会将StudentCourseDTO更改为:

class StudentCourseDTO {

    String uuid;

    String registrationDate;

}

然后你会反序列化对

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

对于每个Resource<StudentCourseDTO>,您可以按照studentcourse的链接进行操作,例如使用RestTemplate检索资源。

当然,这为每个响应项提供了两个额外的调用 - 但是避免这种情况的唯一方法是更改​​服务以将此信息嵌入列表资源中。