Patrick Derckx
Patrick Derckx

Reputation: 201

Java Rest Client bodyToMono generic

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;
    }
    
    ...

}

Upvotes: 1

Views: 5982

Answers (1)

Toerktumlare
Toerktumlare

Reputation: 14819

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.

Upvotes: 8

Related Questions