2016-08-08 53 views
2

I /studentCourses Endpunkt auf dem Server (gebaut mit Spring Data REST), die den folgenden Inhalt zurückgibt:Wie kann Spring HATEOAS REST-Ressourcen mit Links zu anderen Ressourcen verwendet werden?

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

und die folgenden 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(); 

Das Problem ist, dass StudentCourseDTO.student und StudentCourseDTO.course sind immer null, aber StudentCourseDTO.uuid und StudentCourseDTO.registrationDate werden korrekt vom Server abgerufen.
Hat jemand eine Idee, was ich verpasst habe?
Ich denke, es muss etwas zu sagen RestTemplate zu folgen automatisch die Links in den zurückgegebenen Inhalt wie student und course im obigen Beispiel, aber ich habe keinen Weg gefunden, dies zu tun.

+0

Ich würde davon abraten, diesen Links automatisch zu folgen. Wahrscheinlich möchten Sie nur die Informationen abrufen, die Sie benötigen, um die IO zu reduzieren, die Serverlast zu reduzieren und die Einfachheit zu erhöhen. – GuiSim

Antwort

0

Nur weil es Links gibt, heißt das nicht, dass sie automatisch befolgt werden.

Ich würde das ändern StudentCourseDTO zu:

class StudentCourseDTO { 

    String uuid; 

    String registrationDate; 

} 

Und dann würden Sie die Antwort auf eine

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

Für jede Resource<StudentCourseDTO> deserialisieren Sie die Links für student und course dann folgen kann, z.B. Verwenden Sie die RestTemplate, um die Ressourcen abzurufen.

Natürlich gibt es zwei zusätzliche Anrufe pro Antwortelement - aber die einzige Möglichkeit, dies zu vermeiden, ist, den Dienst zu ändern, um diese Informationen in die Listenressource einzubetten.