From 5f74daf4bd02b65df4e9dfa8be4acff751fb5a21 Mon Sep 17 00:00:00 2001 From: "Greg L. Turnquist" Date: Tue, 20 Oct 2020 16:24:26 -0500 Subject: [PATCH] Upgrade to Spring Boot 2.3 and related changes. --- affordances/README.adoc | 10 +++++----- .../hateoas/examples/EmployeeController.java | 10 +++++----- api-evolution/README.adoc | 7 ++++--- .../springframework/hateoas/examples/ClientConfig.java | 9 ++++++--- .../hateoas/examples/HomeController.java | 7 ++++--- .../springframework/hateoas/examples/ClientConfig.java | 9 ++++++--- .../hateoas/examples/HomeController.java | 5 +++-- hypermedia/README.adoc | 2 +- .../hateoas/examples/EmployeeController.java | 2 +- .../hateoas/examples/SupervisorController.java | 2 +- pom.xml | 2 +- simplified/README.adoc | 6 +++--- .../hateoas/examples/EmployeeController.java | 8 ++++---- 13 files changed, 44 insertions(+), 35 deletions(-) diff --git a/affordances/README.adoc b/affordances/README.adoc index d238067..0f3ab3a 100644 --- a/affordances/README.adoc +++ b/affordances/README.adoc @@ -128,7 +128,7 @@ class EmployeeController { ResponseEntity>> findAll() { List> employeeResources = StreamSupport.stream(repository.findAll().spliterator(), false) - .map(employee -> new EntityModel<>(employee, + .map(employee -> EntityModel.of(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, employee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(employee.getId()))), @@ -136,7 +136,7 @@ class EmployeeController { )) .collect(Collectors.toList()); - return ResponseEntity.ok(new CollectionModel<>(employeeResources, + return ResponseEntity.ok(CollectionModel.of(employeeResources, linkTo(methodOn(EmployeeController.class).findAll()).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).newEmployee(null))))); } @@ -146,7 +146,7 @@ class EmployeeController { Employee savedEmployee = repository.save(employee); - return new EntityModel<>(savedEmployee, + return EntityModel.of(savedEmployee, linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, savedEmployee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(savedEmployee.getId()))), @@ -207,7 +207,7 @@ class EmployeeController { ResponseEntity> findOne(@PathVariable long id) { return repository.findById(id) - .map(employee -> new EntityModel<>(employee, + .map(employee -> EntityModel.of(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, employee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(employee.getId()))), @@ -225,7 +225,7 @@ class EmployeeController { Employee updatedEmployee = repository.save(employeeToUpdate); - return new EntityModel<>(updatedEmployee, + return EntityModel.of(updatedEmployee, linkTo(methodOn(EmployeeController.class).findOne(updatedEmployee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, updatedEmployee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(updatedEmployee.getId()))), diff --git a/affordances/src/main/java/org/springframework/hateoas/examples/EmployeeController.java b/affordances/src/main/java/org/springframework/hateoas/examples/EmployeeController.java index 3ef75dc..c03dad0 100644 --- a/affordances/src/main/java/org/springframework/hateoas/examples/EmployeeController.java +++ b/affordances/src/main/java/org/springframework/hateoas/examples/EmployeeController.java @@ -52,14 +52,14 @@ class EmployeeController { ResponseEntity>> findAll() { List> employeeResources = StreamSupport.stream(repository.findAll().spliterator(), false) - .map(employee -> new EntityModel<>(employee, + .map(employee -> EntityModel.of(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, employee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(employee.getId()))), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) .collect(Collectors.toList()); - return ResponseEntity.ok(new CollectionModel<>( // + return ResponseEntity.ok(CollectionModel.of( // employeeResources, // linkTo(methodOn(EmployeeController.class).findAll()).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).newEmployee(null))))); @@ -70,7 +70,7 @@ class EmployeeController { Employee savedEmployee = repository.save(employee); - return new EntityModel<>(savedEmployee, + return EntityModel.of(savedEmployee, linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, savedEmployee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(savedEmployee.getId()))), @@ -91,7 +91,7 @@ class EmployeeController { ResponseEntity> findOne(@PathVariable long id) { return repository.findById(id) - .map(employee -> new EntityModel<>(employee, + .map(employee -> EntityModel.of(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, employee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(employee.getId()))), @@ -108,7 +108,7 @@ class EmployeeController { Employee updatedEmployee = repository.save(employeeToUpdate); - return new EntityModel<>(updatedEmployee, + return EntityModel.of(updatedEmployee, linkTo(methodOn(EmployeeController.class).findOne(updatedEmployee.getId())).withSelfRel() .andAffordance(afford(methodOn(EmployeeController.class).updateEmployee(null, updatedEmployee.getId()))) .andAffordance(afford(methodOn(EmployeeController.class).deleteEmployee(updatedEmployee.getId()))), diff --git a/api-evolution/README.adoc b/api-evolution/README.adoc index 6103672..8ec3bea 100644 --- a/api-evolution/README.adoc +++ b/api-evolution/README.adoc @@ -189,8 +189,8 @@ public class HomeController { private final RestTemplate rest; - public HomeController(RestTemplate restTemplate) { - this.rest = restTemplate; + public HomeController(RestTemplateBuilder restTemplateBuilder) { + this.rest = restTemplateBuilder.build(); } ... } @@ -202,7 +202,8 @@ service. So in this example, it is hard coded into place. WARNING: For fault tolerant production systems, hard coded URIs are NOT recommended. Instead, use something like Spring Cloud Netflix and it's Eureka/Ribbon features to allow https://spring.io/guides/gs/service-registration-and-discovery/[service discovery] and https://spring.io/guides/gs/client-side-load-balancing/[load balanced calls]. -Parts of the controller must also perform REST calls, so we request a `RestTemplate` in the constructor call, allowing Spring to provide it. +Parts of the controller must also perform REST calls, so we request a `RestTemplateBuilder` in the constructor call, allowing Spring Boot to provide it. +Having been decorated with the `HypermediaRestTemplateConfigurer`, it has all active media types applied. You are free to further customize things before invoking the `build()` operation that yields a `RestTemplate`. To construct a listing of all employees, check out the following controller method: diff --git a/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java b/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java index 3cdfa33..2c58295 100644 --- a/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java +++ b/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java @@ -15,9 +15,10 @@ */ package org.springframework.hateoas.examples; +import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; +import org.springframework.hateoas.config.HypermediaRestTemplateConfigurer; /** * @author Greg Turnquist @@ -26,7 +27,9 @@ import org.springframework.web.client.RestTemplate; public class ClientConfig { @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); + RestTemplateCustomizer hypermediaRestTemplateCustomizer(HypermediaRestTemplateConfigurer configurer) { + return restTemplate -> { + configurer.registerHypermediaTypes(restTemplate); + }; } } diff --git a/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/HomeController.java b/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/HomeController.java index 7fb1ce0..551d64c 100644 --- a/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/HomeController.java +++ b/api-evolution/new-client/src/main/java/org/springframework/hateoas/examples/HomeController.java @@ -18,6 +18,7 @@ package org.springframework.hateoas.examples; import java.net.URI; import java.net.URISyntaxException; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; @@ -41,10 +42,10 @@ public class HomeController { private static final String REMOTE_SERVICE_ROOT_URI = "http://localhost:9000"; - private final RestTemplate rest; + private RestTemplate rest; - public HomeController(RestTemplate restTemplate) { - this.rest = restTemplate; + public HomeController(RestTemplateBuilder restTemplateBuilder) { + this.rest = restTemplateBuilder.build(); } /** diff --git a/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java b/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java index 3cdfa33..2c58295 100644 --- a/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java +++ b/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/ClientConfig.java @@ -15,9 +15,10 @@ */ package org.springframework.hateoas.examples; +import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.client.RestTemplate; +import org.springframework.hateoas.config.HypermediaRestTemplateConfigurer; /** * @author Greg Turnquist @@ -26,7 +27,9 @@ import org.springframework.web.client.RestTemplate; public class ClientConfig { @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); + RestTemplateCustomizer hypermediaRestTemplateCustomizer(HypermediaRestTemplateConfigurer configurer) { + return restTemplate -> { + configurer.registerHypermediaTypes(restTemplate); + }; } } diff --git a/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/HomeController.java b/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/HomeController.java index 7b51700..93d285c 100644 --- a/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/HomeController.java +++ b/api-evolution/original-client/src/main/java/org/springframework/hateoas/examples/HomeController.java @@ -18,6 +18,7 @@ package org.springframework.hateoas.examples; import java.net.URI; import java.net.URISyntaxException; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.Link; @@ -43,8 +44,8 @@ public class HomeController { private final RestTemplate rest; - public HomeController(RestTemplate restTemplate) { - this.rest = restTemplate; + public HomeController(RestTemplateBuilder restTemplateBuilder) { + this.rest = restTemplateBuilder.build(); } /** diff --git a/hypermedia/README.adoc b/hypermedia/README.adoc index ac6b0e7..45fa255 100644 --- a/hypermedia/README.adoc +++ b/hypermedia/README.adoc @@ -525,7 +525,7 @@ public class SupervisorController { public ResponseEntity> findOne(@PathVariable Long id) { EntityModel managerResource = controller.findOne(id).getBody(); - EntityModel supervisorResource = new EntityModel<>( + EntityModel supervisorResource = EntityModel.of( new Supervisor(managerResource.getContent()), managerResource.getLinks()); diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java index 5654ee1..315d6bb 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/EmployeeController.java @@ -89,7 +89,7 @@ class EmployeeController { Links newLinks = collectionModel.getLinks().merge(Links.MergeMode.REPLACE_BY_REL, linkTo(methodOn(EmployeeController.class).findEmployees(id)).withSelfRel()); - return ResponseEntity.ok(new CollectionModel<>(collectionModel.getContent(), newLinks)); + return ResponseEntity.ok(CollectionModel.of(collectionModel.getContent(), newLinks)); } @GetMapping("/employees/detailed") diff --git a/hypermedia/src/main/java/org/springframework/hateoas/examples/SupervisorController.java b/hypermedia/src/main/java/org/springframework/hateoas/examples/SupervisorController.java index 1442343..5f9ad97 100644 --- a/hypermedia/src/main/java/org/springframework/hateoas/examples/SupervisorController.java +++ b/hypermedia/src/main/java/org/springframework/hateoas/examples/SupervisorController.java @@ -41,7 +41,7 @@ public class SupervisorController { EntityModel managerResource = controller.findOne(id).getBody(); - EntityModel supervisorResource = new EntityModel<>( // + EntityModel supervisorResource = EntityModel.of( // new Supervisor(managerResource.getContent()), // managerResource.getLinks()); diff --git a/pom.xml b/pom.xml index e03f318..ab3ed9b 100644 --- a/pom.xml +++ b/pom.xml @@ -53,7 +53,7 @@ org.springframework.boot spring-boot-starter-parent - 2.2.6.RELEASE + 2.3.4.RELEASE diff --git a/simplified/README.adoc b/simplified/README.adoc index 9fa1a0b..15a9c58 100644 --- a/simplified/README.adoc +++ b/simplified/README.adoc @@ -96,13 +96,13 @@ The route for the https://martinfowler.com/bliki/DDD_Aggregate.html[aggregate ro ResponseEntity>> findAll() { List> employees = StreamSupport.stream(repository.findAll().spliterator(), false) - .map(employee -> new EntityModel<>(employee, + .map(employee -> EntityModel.of(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) .collect(Collectors.toList()); return ResponseEntity.ok( - new CollectionModel<>(employees, + CollectionModel.of(employees, linkTo(methodOn(EmployeeController.class).findAll()).withSelfRel())); } ---- @@ -133,7 +133,7 @@ To build a single resource, the `/employees/{id}` route is shown below: ResponseEntity> findOne(@PathVariable long id) { return repository.findById(id) - .map(employee -> new EntityModel<>(employee, + .map(employee -> EntityModel.of(employee, linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) .map(ResponseEntity::ok) diff --git a/simplified/src/main/java/org/springframework/hateoas/examples/EmployeeController.java b/simplified/src/main/java/org/springframework/hateoas/examples/EmployeeController.java index 88834c0..23c468a 100644 --- a/simplified/src/main/java/org/springframework/hateoas/examples/EmployeeController.java +++ b/simplified/src/main/java/org/springframework/hateoas/examples/EmployeeController.java @@ -57,13 +57,13 @@ class EmployeeController { ResponseEntity>> findAll() { List> employees = StreamSupport.stream(repository.findAll().spliterator(), false) - .map(employee -> new EntityModel<>(employee, // + .map(employee -> EntityModel.of(employee, // linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), // linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) // .collect(Collectors.toList()); return ResponseEntity.ok( // - new CollectionModel<>(employees, // + CollectionModel.of(employees, // linkTo(methodOn(EmployeeController.class).findAll()).withSelfRel())); } @@ -73,7 +73,7 @@ class EmployeeController { try { Employee savedEmployee = repository.save(employee); - EntityModel employeeResource = new EntityModel<>(savedEmployee, // + EntityModel employeeResource = EntityModel.of(savedEmployee, // linkTo(methodOn(EmployeeController.class).findOne(savedEmployee.getId())).withSelfRel()); return ResponseEntity // @@ -94,7 +94,7 @@ class EmployeeController { ResponseEntity> findOne(@PathVariable long id) { return repository.findById(id) // - .map(employee -> new EntityModel<>(employee, // + .map(employee -> EntityModel.of(employee, // linkTo(methodOn(EmployeeController.class).findOne(employee.getId())).withSelfRel(), // linkTo(methodOn(EmployeeController.class).findAll()).withRel("employees"))) // .map(ResponseEntity::ok) //