I use this code to perform a HTTP POST request and deserialize the returned value:
ParameterizedTypeReference<MyClass> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>("some text");
ResponseEntity<MyClass> result = restTemplate.exchange("/test", HttpMethod.POST, requestEntity, typeRef);
MyClass returnValue = result.getBody();
To make it easier to use, I tried to wrap the code in a function like so:
public <T> T post(Object content, Class<T> returnType, String url){
ParameterizedTypeReference<T> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>(content);
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, typeRef);
return response.getBody();
}
However the code stops functioning when it's put in a function. It throws java.lang.ClassCastException: java.base/java.util.LinkedHashMap cannot be cast to client.rest.MyClass
. It seems as though some type information is lost somewhere along the way.
Here's the complete code in form of 2 test cases:
package client.rest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.support.RestGatewaySupport;
import static org.springframework.test.web.client.ExpectedCount.times;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
class MyClass {
public int getInt(){
return 1;
}
public void setInt(int i){}
}
public class TEMP {
public static RestTemplate restTemplate = new RestTemplate();
public static MockRestServiceServer mockServer;
@BeforeClass
public static void beforeClass() throws JsonProcessingException {
MyClass value = new MyClass();
// set up a mock server
RestGatewaySupport gateway = new RestGatewaySupport();
gateway.setRestTemplate(restTemplate);
mockServer = MockRestServiceServer.bindTo(gateway).build();
ObjectMapper objectmapper = new ObjectMapper();
String payload = objectmapper.writeValueAsString(value);
mockServer.expect(times(2), requestTo("/test"))
.andRespond(withSuccess(payload, MediaType.APPLICATION_JSON));
}
@Test
public void without_function() {
ParameterizedTypeReference<MyClass> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>("some text");
ResponseEntity<MyClass> result = restTemplate.exchange("/test", HttpMethod.POST, requestEntity, typeRef);
MyClass returnValue = result.getBody();
}
public <T> T post(Object content, Class<T> returnType, String url){
ParameterizedTypeReference<T> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>(content);
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, typeRef);
return response.getBody();
}
@Test
public void with_function() {
MyClass returnValue = post("some text", MyClass.class, "/test");
}
}
My question is twofold:
- Why doesn't the function work?
- How can I make it work?