Last active
May 26, 2024 17:53
-
-
Save ripla/6f1516e3d0c28f4d591303d4060342d4 to your computer and use it in GitHub Desktop.
The different ways of accessing a REST HATEOAS resource created with Spring Data. Using a Spring RestTemplate.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
import org.springframework.boot.web.client.RestTemplateBuilder; | |
import org.springframework.cloud.client.loadbalancer.LoadBalanced; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.hateoas.MediaTypes; | |
import org.springframework.hateoas.hal.Jackson2HalModule; | |
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | |
import org.springframework.web.client.RestTemplate; | |
import com.fasterxml.jackson.databind.DeserializationFeature; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
@Configuration | |
public class RestConfiguration { | |
@Bean | |
@LoadBalanced | |
public RestTemplate restTemplate(RestTemplateBuilder builder) { | |
ObjectMapper mapper = new ObjectMapper(); | |
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, | |
false); | |
mapper.registerModule(new Jackson2HalModule()); | |
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); | |
converter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON)); | |
converter.setObjectMapper(mapper); | |
return builder.messageConverters(converter).build(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.springframework.hateoas.Resources; | |
public class StudentResources extends Resources<Student> { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.stream.Stream; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.core.ParameterizedTypeReference; | |
import org.springframework.hateoas.PagedResources; | |
import org.springframework.hateoas.Resource; | |
import org.springframework.hateoas.Resources; | |
import org.springframework.hateoas.mvc.TypeReferences; | |
import org.springframework.http.HttpMethod; | |
import org.springframework.http.ResponseEntity; | |
import org.springframework.stereotype.Component; | |
import org.springframework.web.client.RestTemplate; | |
@Component | |
public class StudentsClient { | |
private static final String URL = "http://students-service/students?page={page}&size={size}"; | |
@Autowired | |
RestTemplate template; | |
public Stream<Student> getStudents(int offset, int limit) { | |
Map<String, Integer> params = new HashMap<>(); | |
params.put("page", offset / limit); | |
params.put("size", limit); | |
// Using external class | |
final ResponseEntity<StudentResources> studentResponse = template | |
.getForEntity(URL, StudentResources.class, params); | |
// Using instantiated ParametrizedTypeReference Resources | |
final ResponseEntity<Resources<Student>> studentResponse = template | |
.exchange(URL, HttpMethod.GET, null, | |
new ParameterizedTypeReference<Resources<Student>>() { | |
}, params); | |
// Using instantiated ParametrizedTypeReference Resources | |
final ResponseEntity<PagedResources<Student>> studentResponse = template | |
.exchange(URL, HttpMethod.GET, null, | |
new ParameterizedTypeReference<PagedResources<Student>>() { | |
}, params); | |
// Does not work for some reason, ends up with empty Resources inside Resources | |
// final ResponseEntity<Resources<Resource<Student>>> studentResponse = template | |
// .exchange(URL, HttpMethod.GET, null, | |
// new TypeReferences.ResourcesType<Resource<Student>>() { | |
// }, params); | |
// Using provided PagedResources type class, note the required {} | |
// This is used for return | |
final ResponseEntity<PagedResources<Resource<Student>>> studentResponse = | |
template | |
.exchange(URL, HttpMethod.GET, null, | |
new TypeReferences.PagedResourcesType<Resource<Student>>(){}, | |
params); | |
return studentResponse.getBody().getContent().stream() | |
.map(Resource::getContent); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm struggling now with List of Objects (simple Objects work!) that's why I wanted to change my Code to use the suggestion in the blog. I get the error "Could not autowire. No beans of 'HypermediaRestTemplateConfigurer' type found.". If I write the following:
the problem isn't solved. Do you have an idea what I'm doing wrong?