My application have some services to different rest endpoints. The Logic is always the same, so I wanted to use inheritance and generics to avoid code duplication. But one line (bodyToMono(E[].class)
) does not work. Is there an alternative (maybe best practice way) to go, I don't see?
Parent Class:
@Configuration
@Service
public abstract class AbstractEntitiesRestService<E>{
protected abstract String getBaseUrl();
@Autowired
@Qualifier("webClient")
protected WebClient WebClient;
@Override
public E[] getObjectsFromCustomQueryImpl(CustomQuery query) {
return jtWebClient.get()
.uri(getBaseUrl())
.retrieve()
.bodyToMono(E[].class) <---- Error!
.block();
}
}
Child Class:
@Configuration
@Service
public class UserService extends AbstractEntitiesRestService<User> {
@Value("${endpoint}")
protected String baseUrl;
@Override
protected String getBaseUrl(){
return baseUrl;
}
...
}
an array []
is not a type, so it can't be generalized.
so T[].class
is an error since an array is not a class
.
You need to use a class that holds types, since types can be generic. For instance an ArrayList
.
@Override
public List<T> getObjectsFromCustomQueryImpl(CustomQuery query) {
return jtWebClient.get()
.uri(getBaseUrl())
.retrieve()
.bodyToMono(new ParameterizedTypeReference<List<T>>() {})
.block();
}
ArrayList
is an implementation of the List<T>
interface. But we cant place an interface containing a generic, List<T>.class
wont work either so spring has a specific class ParameterizedTypeReference
that is a class that will hold the type information for you, during de/serialization.