Skip to content

Commit f542a4a

Browse files
Trixi-TurnyTrixi Turny
andauthored
Bael 4457 list of json objects with rest template (#10058)
* Add users.json * BAEL-4457 demo app with Object array and ParameterizedTypeReference example * BAEL-4457 write unit tests * BAEL-4456 remove new directory * BAEL-4457 fix pom and testname * BAEL-4457 use default target release * BAEL-4457 add more examples of processing the objects and address comments * BAEL-4457 remove new ArrayList and put @responsebody before public * BAEL-4457 use static userJson object * BAEL-4456 tidy up extra spaces * BAEL-4457 removed too many brackets * BAEL-4457 remove incorrect assertion * BAEL-4457 use a service instead of another controller * BAEL-4457 use ObjectMapper to extract usernames from objects * BAEL-4457 fix UserController * BAEL-4457 delete provider service and controller * BAEL-4457 use functional interface where possible * BAEL-4457 remove unnecessary annotations and tidy indents for exchange() * BAEL-4457 use @JsonCreator and @JsonProperty and resolve comments * BAEL-4457 improve comment * BAEL-4457 remove comments and use assertj core lib for assertions * BAEL-4457 fix indents Co-authored-by: Trixi Turny <writetotrixi@gmail.com>
1 parent 83e87ae commit f542a4a

6 files changed

Lines changed: 299 additions & 7 deletions

File tree

spring-resttemplate-2/pom.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@
7171
<groupId>ch.qos.logback</groupId>
7272
<artifactId>logback-classic</artifactId>
7373
</dependency>
74-
74+
7575
</dependencies>
76-
76+
7777
<build>
7878
<plugins>
79-
<plugin>
80-
<groupId>org.springframework.boot</groupId>
81-
<artifactId>spring-boot-maven-plugin</artifactId>
82-
</plugin>
79+
<plugin>
80+
<groupId>org.springframework.boot</groupId>
81+
<artifactId>spring-boot-maven-plugin</artifactId>
82+
</plugin>
8383
</plugins>
8484
</build>
8585

86-
</project>
86+
</project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.baeldung.resttemplate.json.consumer.service;
2+
3+
import java.util.List;
4+
5+
public interface UserConsumerService {
6+
7+
List<String> processUserDataFromObjectArray();
8+
9+
List<String> processUserDataFromUserArray();
10+
11+
List<String> processUserDataFromUserList();
12+
13+
List<String> processNestedUserDataFromUserArray();
14+
15+
List<String> processNestedUserDataFromUserList();
16+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.baeldung.resttemplate.json.consumer.service;
2+
3+
import com.baeldung.resttemplate.json.model.Address;
4+
import com.baeldung.resttemplate.json.model.User;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import org.springframework.core.ParameterizedTypeReference;
7+
import org.springframework.http.HttpMethod;
8+
import org.springframework.http.HttpStatus;
9+
import org.springframework.http.MediaType;
10+
import org.springframework.http.ResponseEntity;
11+
import org.springframework.web.client.RestTemplate;
12+
13+
import java.util.Arrays;
14+
import java.util.List;
15+
import java.util.stream.Collectors;
16+
17+
public class UserConsumerServiceImpl implements UserConsumerService {
18+
19+
private static final String BASE_URL = "http://localhost:8080/users";
20+
private final RestTemplate restTemplate;
21+
private static final ObjectMapper mapper = new ObjectMapper();
22+
23+
public UserConsumerServiceImpl(RestTemplate restTemplate) {
24+
this.restTemplate = restTemplate;
25+
}
26+
27+
@Override
28+
public List<String> processUserDataFromObjectArray() {
29+
ResponseEntity<Object[]> responseEntity = restTemplate.getForEntity(BASE_URL, Object[].class);
30+
Object[] objects = responseEntity.getBody();
31+
return Arrays.stream(objects)
32+
.map(object -> mapper.convertValue(object, User.class))
33+
.map(User::getName)
34+
.collect(Collectors.toList());
35+
}
36+
37+
@Override
38+
public List<String> processUserDataFromUserArray() {
39+
ResponseEntity<User[]> responseEntity = restTemplate.getForEntity(BASE_URL, User[].class);
40+
User[] userArray = responseEntity.getBody();
41+
return Arrays.stream(userArray)
42+
.map(User::getName)
43+
.collect(Collectors.toList());
44+
}
45+
46+
@Override
47+
public List<String> processUserDataFromUserList() {
48+
ResponseEntity<List<User>> responseEntity =
49+
restTemplate.exchange(
50+
BASE_URL,
51+
HttpMethod.GET,
52+
null,
53+
new ParameterizedTypeReference<List<User>>() {}
54+
);
55+
List<User> users = responseEntity.getBody();
56+
return users.stream()
57+
.map(User::getName)
58+
.collect(Collectors.toList());
59+
}
60+
61+
@Override
62+
public List<String> processNestedUserDataFromUserArray() {
63+
ResponseEntity<User[]> responseEntity = restTemplate.getForEntity(BASE_URL, User[].class);
64+
User[] userArray = responseEntity.getBody();
65+
//we can get more info if we need :
66+
MediaType contentType = responseEntity.getHeaders().getContentType();
67+
HttpStatus statusCode = responseEntity.getStatusCode();
68+
69+
return Arrays.stream(userArray)
70+
.flatMap(user -> user.getAddressList().stream())
71+
.map(Address::getPostCode)
72+
.collect(Collectors.toList());
73+
}
74+
75+
@Override
76+
public List<String> processNestedUserDataFromUserList() {
77+
ResponseEntity<List<User>> responseEntity =
78+
restTemplate.exchange(
79+
BASE_URL,
80+
HttpMethod.GET,
81+
null,
82+
new ParameterizedTypeReference<List<User>>() {}
83+
);
84+
List<User> userList = responseEntity.getBody();
85+
return userList.stream()
86+
.flatMap(user -> user.getAddressList().stream())
87+
.map(Address::getPostCode)
88+
.collect(Collectors.toList());
89+
}
90+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.baeldung.resttemplate.json.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonInclude;
5+
import com.fasterxml.jackson.annotation.JsonProperty;
6+
7+
8+
@JsonInclude(JsonInclude.Include.NON_NULL)
9+
public class Address {
10+
private final String addressLine1;
11+
private final String addressLine2;
12+
private final String town;
13+
private final String postCode;
14+
15+
@JsonCreator
16+
public Address(
17+
@JsonProperty("addressLine1") String addressLine1,
18+
@JsonProperty("addressLine2") String addressLine2,
19+
@JsonProperty("town") String town,
20+
@JsonProperty("postCode") String postCode) {
21+
this.addressLine1 = addressLine1;
22+
this.addressLine2 = addressLine2;
23+
this.town = town;
24+
this.postCode = postCode;
25+
}
26+
public String getPostCode() {
27+
return postCode;
28+
}
29+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.baeldung.resttemplate.json.model;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonInclude;
5+
import com.fasterxml.jackson.annotation.JsonProperty;
6+
7+
import java.util.List;
8+
9+
@JsonInclude(JsonInclude.Include.NON_NULL)
10+
public class User {
11+
private final int id;
12+
private final String name;
13+
private final List<Address> addressList;
14+
15+
@JsonCreator
16+
public User(
17+
@JsonProperty("id") int id,
18+
@JsonProperty("name") String name,
19+
@JsonProperty("addressList") List<Address> addressList) {
20+
this.id = id;
21+
this.name = name;
22+
this.addressList = addressList;
23+
}
24+
25+
public String getName() {
26+
return name;
27+
}
28+
29+
public List<Address> getAddressList() { return addressList; }
30+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.baeldung.resttemplate.json.consumer.service;
2+
3+
import org.junit.Before;
4+
import org.junit.Test;
5+
import org.springframework.boot.test.context.SpringBootTest;
6+
import org.springframework.http.HttpMethod;
7+
import org.springframework.http.HttpStatus;
8+
import org.springframework.http.MediaType;
9+
import org.springframework.test.web.client.ExpectedCount;
10+
import org.springframework.test.web.client.MockRestServiceServer;
11+
import org.springframework.web.client.RestTemplate;
12+
13+
import java.util.Arrays;
14+
import java.util.List;
15+
16+
import static org.assertj.core.api.Assertions.assertThat;
17+
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
18+
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
19+
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
20+
21+
@SpringBootTest
22+
public class UserConsumerServiceImplUnitTest {
23+
24+
private static String USER_JSON = "[{\"id\":1,\"name\":\"user1\",\"addressList\":[{\"addressLine1\":\"address1_addressLine1\",\"addressLine2\":\"address1_addressLine2\",\"town\":\"address1_town\",\"postCode\":\"user1_address1_postCode\"}," +
25+
"{\"addressLine1\":\"address2_addressLine1\",\"addressLine2\":\"address2_addressLine2\",\"town\":\"address2_town\",\"postCode\":\"user1_address2_postCode\"}]}," +
26+
"{\"id\":2,\"name\":\"user2\",\"addressList\":[{\"addressLine1\":\"address1_addressLine1\",\"addressLine2\":\"address1_addressLine2\",\"town\":\"address1_town\",\"postCode\":\"user2_address1_postCode\"}]}]";
27+
28+
private MockRestServiceServer mockServer;
29+
private final RestTemplate restTemplate = new RestTemplate();
30+
private final UserConsumerService tested = new UserConsumerServiceImpl(restTemplate);
31+
32+
@Before
33+
public void init() {
34+
mockServer = MockRestServiceServer.createServer(restTemplate);
35+
}
36+
37+
@Test
38+
public void whenProcessUserDataAsObjects_thenOK() {
39+
String url = "http://localhost:8080/users";
40+
List<String> expected = Arrays.asList("user1", "user2");
41+
42+
mockServer.expect(ExpectedCount.once(),
43+
requestTo(url))
44+
.andExpect(method(HttpMethod.GET))
45+
.andRespond(withStatus(HttpStatus.OK)
46+
.contentType(MediaType.APPLICATION_JSON)
47+
.body(USER_JSON));
48+
49+
List<String> actual = tested.processUserDataFromObjectArray();
50+
51+
mockServer.verify();
52+
assertThat(actual).containsExactly(expected.get(0), expected.get(1));
53+
}
54+
55+
@Test
56+
public void whenProcessUserDataAsArray_thenOK() {
57+
String url = "http://localhost:8080/users";
58+
List<String> expected = Arrays.asList("user1", "user2");
59+
60+
mockServer.expect(ExpectedCount.once(),
61+
requestTo(url))
62+
.andExpect(method(HttpMethod.GET))
63+
.andRespond(withStatus(HttpStatus.OK)
64+
.contentType(MediaType.APPLICATION_JSON)
65+
.body(USER_JSON));
66+
67+
List<String> actual = tested.processUserDataFromUserArray();
68+
69+
mockServer.verify();
70+
assertThat(actual).containsExactly(expected.get(0), expected.get(1));
71+
}
72+
73+
@Test
74+
public void whenProcessUserDataAsList_thenOK() {
75+
String url = "http://localhost:8080/users";
76+
List<String> expected = Arrays.asList("user1", "user2");
77+
78+
mockServer.expect(ExpectedCount.once(),
79+
requestTo(url))
80+
.andExpect(method(HttpMethod.GET))
81+
.andRespond(withStatus(HttpStatus.OK)
82+
.contentType(MediaType.APPLICATION_JSON)
83+
.body(USER_JSON));
84+
85+
List<String> actual = tested.processUserDataFromUserList();
86+
87+
mockServer.verify();
88+
assertThat(actual).containsExactly(expected.get(0), expected.get(1));
89+
}
90+
91+
92+
@Test
93+
public void whenProcessNestedUserDataFromArray_thenOK() {
94+
String url = "http://localhost:8080/users";
95+
List<String> expected = Arrays.asList("user1_address1_postCode", "user1_address2_postCode", "user2_address1_postCode");
96+
97+
mockServer.expect(ExpectedCount.once(),
98+
requestTo(url))
99+
.andExpect(method(HttpMethod.GET))
100+
.andRespond(withStatus(HttpStatus.OK)
101+
.contentType(MediaType.APPLICATION_JSON)
102+
.body(USER_JSON));
103+
104+
List<String> actual = tested.processNestedUserDataFromUserArray();
105+
106+
mockServer.verify();
107+
assertThat(actual).containsExactly(expected.get(0), expected.get(1), expected.get(2));
108+
}
109+
110+
@Test
111+
public void whenProcessNestedUserDataFromList_thenOK() {
112+
String url = "http://localhost:8080/users";
113+
List<String> expected = Arrays.asList("user1_address1_postCode", "user1_address2_postCode", "user2_address1_postCode");
114+
115+
mockServer.expect(ExpectedCount.once(),
116+
requestTo(url))
117+
.andExpect(method(HttpMethod.GET))
118+
.andRespond(withStatus(HttpStatus.OK)
119+
.contentType(MediaType.APPLICATION_JSON)
120+
.body(USER_JSON));
121+
122+
List<String> actual = tested.processNestedUserDataFromUserList();
123+
124+
mockServer.verify();
125+
assertThat(actual).containsExactly(expected.get(0), expected.get(1), expected.get(2));
126+
}
127+
}

0 commit comments

Comments
 (0)