I am an advanced C# developer who is learning Java via Spring. Most of my coding uses generics for algorithm processing. Part of the skill is to use type references (T, R, K, etc) instead of actual classes in my algorithms.
I am having a difficult time with creating a generic method that uses the RestTemplate
exchange
method.
public abstract class ServiceRepository<T extends Serializable, R extends Class> {
private RestTemplate restTemplate;
public R executeRequest(HttpMethod method){
return restTemplate.exchange(
getUrl(),
method,
buildRequestEntity(),
R)
.getBody();
}
protected abstract RequestEntity<T> buildRequestEntity();
protected abstract String getUrl();
}
In my algorithm, which will eventually have error handling, and further processing of the request, I want to use generics throughout. It seems like your implementation requires a class to be defined, instead of accepting the generic value (R) for the response. In my research, it has been noted that it is impossible for the compiler to manage a generic in the response type parameter.
- Is there a way I can use this method using a generic type for the response's body?
- Is it feasible to create a new method overload that handles generics directly w/o having to use the
.class
method for the parameter? - Is this a Java issue and Spring is limited to what the Java compiler gives them?
Thanks
Comment From: sbrannen
Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.
The above is our general policy for questions of this nature.
However, having said that, something like the following is probably what you're looking for.
public abstract class ServiceRepository<T extends Serializable, R> {
private final RestTemplate restTemplate;
private final Class<R> returnType;
@SuppressWarnings("unchecked")
public ServiceRepository(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.returnType = (Class<R>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
public R executeRequest(HttpMethod method) {
return this.restTemplate.exchange(getUrl(), method, buildRequestEntity(), this.returnType).getBody();
}
protected abstract RequestEntity<T> buildRequestEntity();
protected abstract String getUrl();
}
Comment From: tharper1977
Sam
Thanks for your suggestion. Like I said, I came from the C# world, and that world was very open to improve libraries based upon the suggestion.
Following the DRY pattern, it would make sense to overload the RestTemplate.exchange(…) method in a way that every time someone wants to use generics on tis type of call, that your implementation would execute the code in the method below.
public ServiceRepository(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.returnType = (Class
To me, it is a small, but effective enhancement to the tool that developers would take advantage of.
Given your closure of the suggestion, I will give this a shot and see if it accomplishes the task I am working in.
From: Sam Brannen @.> Sent: Thursday, March 23, 2023 10:10 AM To: spring-projects/spring-framework @.> Cc: Tom Harper @.>; Author @.> Subject: Re: [spring-projects/spring-framework] RestTemplate.exchange issue (Issue #30178)
Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow http://stackoverflow.com/ . As mentioned in the guidelines for contributing https://github.com/spring-projects/spring-framework/blob/master/CONTRIBUTING.md#discuss , we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.
The above is our general policy for questions of this nature.
However, having said that, something like the following is probably what you're looking for.
public abstract class ServiceRepository
private final RestTemplate restTemplate;
private final Class<R> returnType;
@SuppressWarnings("unchecked")
public ServiceRepository(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
this.returnType = (Class<R>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
public R executeRequest(HttpMethod method) {
return this.restTemplate.exchange(getUrl(), method, buildRequestEntity(), this.returnType).getBody();
}
protected abstract RequestEntity<T> buildRequestEntity();
protected abstract String getUrl();
}
— Reply to this email directly, view it on GitHub https://github.com/spring-projects/spring-framework/issues/30178#issuecomment-1481369367 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AHDIWUCVOU6L3PW46VRVFVDW5RRT5ANCNFSM6AAAAAAWFG2C5Q . You are receiving this because you authored the thread. https://github.com/notifications/beacon/AHDIWUECIL3HG6NZTCUIM5LW5RRT5A5CNFSM6AAAAAAWFG2C5SWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTSYJPTRO.gif Message ID: @. @.> >