Obter e publicar listas de objetos com RestTemplate
1. Introdução
A classeRestTemplate é a ferramenta central para executar operações HTTP do lado do cliente no Spring. Ele fornece vários métodos utilitários para criar solicitações HTTP e manipular respostas.
E, comoRestTemplate se integra bem comJackson,, ele pode serializar / desserializar a maioria dos objetos de e para JSON sem muito esforço. No entanto,working with collections of objects is not so straightforward.
Neste tutorial, veremos como usarRestTemplate paraGET ePOST uma lista de objetos.
Leitura adicional:
Tratamento de erros RestTemplate de primavera
Aprenda a lidar com erros com RestTemplate de Spring
Solicitação de postagem RestTemplate com JSON
Aprenda a usar o RestTemplate do Spring para enviar solicitações com conteúdo JSON.
2. Serviço de exemplo
Usaremos uma API de funcionário que possui dois pontos de extremidade HTTP - obtenha tudo e crie:
-
GET / funcionários
-
POST / funcionários
Para a comunicação entre o cliente e o servidor, usaremos um DTO simples para encapsular os dados básicos dos funcionários:
public class Employee {
public long id;
public String title;
// standard constructor and setters/getters
}
Agora estamos prontos para escrever um código que useRestTemplate para obter e criar listas de objetosEmployee.
3. Obtenha uma lista de objetos comRestTemplate
Normalmente, ao chamar GET, você pode usar um dos métodos simplificados emRestTemplate, como:
getForObject (url URI, classe
Isso envia uma solicitação para o URI especificado usando o verbo GET e converte o corpo da resposta no tipo Java solicitado. Isso funciona muito bem para a maioria das classes, mas tem uma limitação:we cannot send lists of objects.
O problema ocorre devido ao apagamento do tipo com genéricos Java. Quando o aplicativo está sendo executado, ele não tem conhecimento de que tipo de objeto está na lista. This means the data in the list cannot be deserialized into the appropriate type.
Felizmente, temos duas opções para contornar isso.
3.1. Usando matrizes
Primeiro, podemos usarRestTemplate.getForObject() to GET um array de objetos por meio do parâmetroresponseType. Qualquer que seja oclass que especificarmos, ele corresponderá ao tipo de parâmetro deResponseEntity:
ResponseEntity response =
restTemplate.getForEntity(
"http://localhost:8080/employees/",
Employee[].class);
Employee[] employees = response.getBody();
Além disso, poderíamos ter usadoRestTemplate.exchange para obter o mesmo resultado.
Observe que o colaborador que está fazendo o trabalho pesado aqui éResponseExtractor, , portanto, se precisarmos de mais personalização, podemos chamarexecutee fornecer nossa própria instância.
3.2. Usando uma classe Wrapper
Algumas APIs retornarão um objeto de nível superior que contém a lista de funcionários em vez de retornar a lista diretamente. Para lidar com essa situação, podemos usar uma classe de wrapper que contém a lista de funcionários.
public class EmployeeList {
private List employees;
public EmployeeList() {
employees = new ArrayList<>();
}
// standard constructor and getter/setter
}
Agora podemos usar o métodogetForObject() mais simples para obter a lista de funcionários:
EmployeeList response = restTemplate.getForObject(
"http://localhost:8080/employees",
EmployeeList.class);
List employees = response.getEmployees();
Esse código é muito mais simples, mas requer um objeto wrapper adicional.
4. Publique uma lista de objetos comRestTemplate
Agora vamos ver como enviar uma lista de objetos de nosso cliente para o servidor. Assim como acima,RestTemplate fornece um método simplificado para chamar POST:
postForObject (url URI, solicitação de objeto, classe
Isso envia um HTTP POST para o URI fornecido, com o corpo da solicitação opcional, e converte a resposta no tipo especificado. Ao contrário do cenário GET acima,we don’t have to worry about type erasure.
Isso ocorre porque agora estamos indo de objetos Java para JSON. A lista de objetos e seu tipo são conhecidos pela JVM e, portanto, devem ser serializados corretamente:
List newEmployees = new ArrayList<>();
newEmployees.add(new Employee(3, "Intern"));
newEmployees.add(new Employee(4, "CEO"));
restTemplate.postForObject(
"http://localhost:8080/employees/",
newEmployees,
ResponseEntity.class);
4.1. Usando uma classe Wrapper
Se precisarmos usar uma classe de wrapper para ser consistente com o cenário GET acima, isso também é simples. Podemos enviar uma nova lista usandoRestTemplate:
List newEmployees = new ArrayList<>();
newEmployees.add(new Employee(3, "Intern"));
newEmployees.add(new Employee(4, "CEO"));
restTemplate.postForObject(
"http://localhost:8080/employees",
new EmployeeList(newEmployees),
ResponseEntity.class);
5. Conclusão
O uso do RestTemplate é uma maneira simples de criar clientes HTTP para se comunicar com seus serviços.
Ele fornece vários métodos para trabalhar com todos os métodos HTTP e objetos simples. Com um pouco de código extra, podemos usá-lo facilmente para trabalhar com listas de objetos.
Como de costume, o código completo está disponível emGithub project.