diff --git a/spring-core-4/pom.xml b/spring-core-4/pom.xml
index 1bbbb2dd5dfc..15c2e1037617 100644
--- a/spring-core-4/pom.xml
+++ b/spring-core-4/pom.xml
@@ -5,6 +5,18 @@
4.0.0
spring-core-4
spring-core-4
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 17
+ 17
+
+
+
+
com.baeldung
@@ -70,6 +82,44 @@
commons-text
${commons-text.version}
+
+ org.springframework
+ spring-webflux
+ ${spring-webflux.version}
+
+
+ org.mockito
+ mockito-junit-jupiter
+ ${mockito.version}
+ test
+
+
+ io.projectreactor
+ reactor-test
+ ${reactor.version}
+ test
+
+
+ com.github.tomakehurst
+ wiremock-jre8-standalone
+ ${wiremock.version}
+ test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson.version}
+
@@ -77,6 +127,11 @@
6.1.0
3.0.0
1.10.0
+ 6.2.9
+ 5.18.0
+ 3.7.8
+ 2.35.0
+ 2.19.1
diff --git a/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiException.java b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiException.java
new file mode 100644
index 000000000000..a6710f5eb590
--- /dev/null
+++ b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiException.java
@@ -0,0 +1,12 @@
+package com.baeldung.parametrizedtypereference;
+
+public class ApiException extends RuntimeException {
+
+ public ApiException(String message) {
+ super(message);
+ }
+
+ public ApiException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiResponse.java b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiResponse.java
new file mode 100644
index 000000000000..290fff4ff186
--- /dev/null
+++ b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiResponse.java
@@ -0,0 +1,5 @@
+package com.baeldung.parametrizedtypereference;
+
+public record ApiResponse(boolean success, String message, T data) {
+
+}
diff --git a/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiService.java b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiService.java
new file mode 100644
index 000000000000..5f1e2812a6f8
--- /dev/null
+++ b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ApiService.java
@@ -0,0 +1,70 @@
+package com.baeldung.parametrizedtypereference;
+
+import static com.baeldung.parametrizedtypereference.TypeReferences.USER_LIST;
+
+import java.util.List;
+
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class ApiService {
+
+ private final RestTemplate restTemplate;
+ private final String baseUrl;
+
+ public ApiService(RestTemplate restTemplate, String baseUrl) {
+ this.restTemplate = restTemplate;
+ this.baseUrl = baseUrl;
+ }
+
+ public List fetchUserList() {
+ ParameterizedTypeReference> typeRef = new ParameterizedTypeReference>() {
+ };
+
+ ResponseEntity> response = restTemplate.exchange(baseUrl + "/api/users", HttpMethod.GET, null, typeRef);
+
+ return response.getBody();
+ }
+
+ public List fetchUsersWrongApproach() {
+ ResponseEntity response = restTemplate.getForEntity(baseUrl + "/api/users", List.class);
+
+ return (List) response.getBody();
+ }
+
+ public List fetchUsersCorrectApproach() {
+ ParameterizedTypeReference> typeRef = new ParameterizedTypeReference>() {
+ };
+
+ ResponseEntity> response = restTemplate.exchange(baseUrl + "/api/users", HttpMethod.GET, null, typeRef);
+
+ return response.getBody();
+ }
+
+ public User fetchUser(Long id) {
+ return restTemplate.getForObject(baseUrl + "/api/users/" + id, User.class);
+ }
+
+ public User[] fetchUsersArray() {
+ return restTemplate.getForObject(baseUrl + "/api/users", User[].class);
+ }
+
+ public List fetchUsersList() {
+ ParameterizedTypeReference> typeRef = new ParameterizedTypeReference>() {
+ };
+
+ ResponseEntity> response = restTemplate.exchange(baseUrl + "/api/users", HttpMethod.GET, null, typeRef);
+
+ return response.getBody();
+ }
+
+ public List fetchUsersListWithExistingReference() {
+ ResponseEntity> response = restTemplate.exchange(baseUrl + "/api/users", HttpMethod.GET, null, USER_LIST);
+
+ return response.getBody();
+ }
+}
\ No newline at end of file
diff --git a/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ReactiveApiService.java b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ReactiveApiService.java
new file mode 100644
index 000000000000..d0fbf2e50b76
--- /dev/null
+++ b/spring-core-4/src/main/java/com/baeldung/parametrizedtypereference/ReactiveApiService.java
@@ -0,0 +1,43 @@
+package com.baeldung.parametrizedtypereference;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.stereotype.Service;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import reactor.core.publisher.Mono;
+
+@Service
+public class ReactiveApiService {
+
+ private final WebClient webClient;
+
+ public ReactiveApiService(String baseUrl) {
+ this.webClient = WebClient.builder()
+ .baseUrl(baseUrl)
+ .build();
+ }
+
+ public Mono