Olá Pessoal !
Gostaria de criar um get () genérico para todos os tipos de URI e VO no meu RestService.
Mas eu não sei como definir (e usá-lo) um parâmetro para criar um get genérico (uri, className). Eu tentei isso:
@Service
public class RestService {
private final RestTemplate restTemplate;
public RestService(RestTemplateBuilder restTemplateBuilder) {
// set connection and read timeouts
this.restTemplate = restTemplateBuilder
.setConnectTimeout(Duration.ofSeconds(500))
.setReadTimeout(Duration.ofSeconds(500))
.build();
}
public Object[] get(String uri, Class[] className){
return this.restTemplate.getForObject(uri, className);
}
}
Eu tentei assim:
String uri = "https://jsonplaceholder.typicode.com/posts";
for (Post post : restService.get(uri, Post.class)) {
System.out.println(post.getTitle());
}
E tomei este erro:
(argument mismatch; java.lang.Class[] cannot be converted to java.lang.Class<T>))
Tentei assim também:
public Object get(URI uri, Class<?> className){
return restTemplate.getForObject(uri, className);
}
Entretanto, não fui capaz de iterar o resultado
Então, existe uma maneira de definir um método genérico para um Service?
Class[] indica que você está esperando um vetor de objetos da classe Class.
Class indica que você está esperando um objeto da classe Class que definiu um tipo para o genérico T.
Assim como você pode fazer:
List<String> lista = new Array/List<>(); //Ou new ArrayList<String>();
@celsowm2
Fala dev blz? Eu entendi o que você quer fazer, porém ainda não entendi o por quê, pois o framework Spring é muito completo e o RestTemplate que você está usando já aceita tipos genéricos.
//neste caso ele espera o retorno de um objeto único do tipo Post
restTemplate.postForObject("https://jsonplaceholder.typicode.com/posts", null, Post.class);
//neste caso ele espera o retorno de uma lista de objetos
restTemplate.postForObject("https://jsonplaceholder.typicode.com/posts", null, List.class);
Não existe a necessidade de uma classe Service genérica por que o RestTemplate já é essa classe, a não ser que sinta a necessidade de configurar por classe você pode setar os valores de timeout no application.properties ou application.yml e construir uma classe Service da sequinte forma:
@Service
public class RestService<T> {
@Autowired
public final RestTemplate restTemplate;
public T get(String uri, Class<T> clazz){
return restTemplate.getForObject(uri, null, clazz);
}
public List<T> get(String uri){
return restTemplate.getForObject(uri, null, List.class);
}
}
E mesmo que não esteja fazendo a injeção do service em uma classe gerenciada pelo Spring você pode obter uma instância dele pelo contexto da aplicação.