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>
This commit is contained in:
Trixi-Turny 2020-12-18 09:11:27 +00:00 committed by GitHub
parent 83e87aebc0
commit f542a4afab
6 changed files with 299 additions and 7 deletions

View File

@ -71,16 +71,16 @@
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -0,0 +1,16 @@
package com.baeldung.resttemplate.json.consumer.service;
import java.util.List;
public interface UserConsumerService {
List<String> processUserDataFromObjectArray();
List<String> processUserDataFromUserArray();
List<String> processUserDataFromUserList();
List<String> processNestedUserDataFromUserArray();
List<String> processNestedUserDataFromUserList();
}

View File

@ -0,0 +1,90 @@
package com.baeldung.resttemplate.json.consumer.service;
import com.baeldung.resttemplate.json.model.Address;
import com.baeldung.resttemplate.json.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class UserConsumerServiceImpl implements UserConsumerService {
private static final String BASE_URL = "http://localhost:8080/users";
private final RestTemplate restTemplate;
private static final ObjectMapper mapper = new ObjectMapper();
public UserConsumerServiceImpl(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public List<String> processUserDataFromObjectArray() {
ResponseEntity<Object[]> responseEntity = restTemplate.getForEntity(BASE_URL, Object[].class);
Object[] objects = responseEntity.getBody();
return Arrays.stream(objects)
.map(object -> mapper.convertValue(object, User.class))
.map(User::getName)
.collect(Collectors.toList());
}
@Override
public List<String> processUserDataFromUserArray() {
ResponseEntity<User[]> responseEntity = restTemplate.getForEntity(BASE_URL, User[].class);
User[] userArray = responseEntity.getBody();
return Arrays.stream(userArray)
.map(User::getName)
.collect(Collectors.toList());
}
@Override
public List<String> processUserDataFromUserList() {
ResponseEntity<List<User>> responseEntity =
restTemplate.exchange(
BASE_URL,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<User>>() {}
);
List<User> users = responseEntity.getBody();
return users.stream()
.map(User::getName)
.collect(Collectors.toList());
}
@Override
public List<String> processNestedUserDataFromUserArray() {
ResponseEntity<User[]> responseEntity = restTemplate.getForEntity(BASE_URL, User[].class);
User[] userArray = responseEntity.getBody();
//we can get more info if we need :
MediaType contentType = responseEntity.getHeaders().getContentType();
HttpStatus statusCode = responseEntity.getStatusCode();
return Arrays.stream(userArray)
.flatMap(user -> user.getAddressList().stream())
.map(Address::getPostCode)
.collect(Collectors.toList());
}
@Override
public List<String> processNestedUserDataFromUserList() {
ResponseEntity<List<User>> responseEntity =
restTemplate.exchange(
BASE_URL,
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<User>>() {}
);
List<User> userList = responseEntity.getBody();
return userList.stream()
.flatMap(user -> user.getAddressList().stream())
.map(Address::getPostCode)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.resttemplate.json.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Address {
private final String addressLine1;
private final String addressLine2;
private final String town;
private final String postCode;
@JsonCreator
public Address(
@JsonProperty("addressLine1") String addressLine1,
@JsonProperty("addressLine2") String addressLine2,
@JsonProperty("town") String town,
@JsonProperty("postCode") String postCode) {
this.addressLine1 = addressLine1;
this.addressLine2 = addressLine2;
this.town = town;
this.postCode = postCode;
}
public String getPostCode() {
return postCode;
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.resttemplate.json.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private final int id;
private final String name;
private final List<Address> addressList;
@JsonCreator
public User(
@JsonProperty("id") int id,
@JsonProperty("name") String name,
@JsonProperty("addressList") List<Address> addressList) {
this.id = id;
this.name = name;
this.addressList = addressList;
}
public String getName() {
return name;
}
public List<Address> getAddressList() { return addressList; }
}

View File

@ -0,0 +1,127 @@
package com.baeldung.resttemplate.json.consumer.service;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.client.ExpectedCount;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
@SpringBootTest
public class UserConsumerServiceImplUnitTest {
private static String USER_JSON = "[{\"id\":1,\"name\":\"user1\",\"addressList\":[{\"addressLine1\":\"address1_addressLine1\",\"addressLine2\":\"address1_addressLine2\",\"town\":\"address1_town\",\"postCode\":\"user1_address1_postCode\"}," +
"{\"addressLine1\":\"address2_addressLine1\",\"addressLine2\":\"address2_addressLine2\",\"town\":\"address2_town\",\"postCode\":\"user1_address2_postCode\"}]}," +
"{\"id\":2,\"name\":\"user2\",\"addressList\":[{\"addressLine1\":\"address1_addressLine1\",\"addressLine2\":\"address1_addressLine2\",\"town\":\"address1_town\",\"postCode\":\"user2_address1_postCode\"}]}]";
private MockRestServiceServer mockServer;
private final RestTemplate restTemplate = new RestTemplate();
private final UserConsumerService tested = new UserConsumerServiceImpl(restTemplate);
@Before
public void init() {
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
public void whenProcessUserDataAsObjects_thenOK() {
String url = "http://localhost:8080/users";
List<String> expected = Arrays.asList("user1", "user2");
mockServer.expect(ExpectedCount.once(),
requestTo(url))
.andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(USER_JSON));
List<String> actual = tested.processUserDataFromObjectArray();
mockServer.verify();
assertThat(actual).containsExactly(expected.get(0), expected.get(1));
}
@Test
public void whenProcessUserDataAsArray_thenOK() {
String url = "http://localhost:8080/users";
List<String> expected = Arrays.asList("user1", "user2");
mockServer.expect(ExpectedCount.once(),
requestTo(url))
.andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(USER_JSON));
List<String> actual = tested.processUserDataFromUserArray();
mockServer.verify();
assertThat(actual).containsExactly(expected.get(0), expected.get(1));
}
@Test
public void whenProcessUserDataAsList_thenOK() {
String url = "http://localhost:8080/users";
List<String> expected = Arrays.asList("user1", "user2");
mockServer.expect(ExpectedCount.once(),
requestTo(url))
.andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(USER_JSON));
List<String> actual = tested.processUserDataFromUserList();
mockServer.verify();
assertThat(actual).containsExactly(expected.get(0), expected.get(1));
}
@Test
public void whenProcessNestedUserDataFromArray_thenOK() {
String url = "http://localhost:8080/users";
List<String> expected = Arrays.asList("user1_address1_postCode", "user1_address2_postCode", "user2_address1_postCode");
mockServer.expect(ExpectedCount.once(),
requestTo(url))
.andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(USER_JSON));
List<String> actual = tested.processNestedUserDataFromUserArray();
mockServer.verify();
assertThat(actual).containsExactly(expected.get(0), expected.get(1), expected.get(2));
}
@Test
public void whenProcessNestedUserDataFromList_thenOK() {
String url = "http://localhost:8080/users";
List<String> expected = Arrays.asList("user1_address1_postCode", "user1_address2_postCode", "user2_address1_postCode");
mockServer.expect(ExpectedCount.once(),
requestTo(url))
.andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(USER_JSON));
List<String> actual = tested.processNestedUserDataFromUserList();
mockServer.verify();
assertThat(actual).containsExactly(expected.get(0), expected.get(1), expected.get(2));
}
}