Ara*_*Fey 3 java generics spring function jackson
我使用此代码执行 HTTP POST 请求并反序列化返回值:
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();
Run Code Online (Sandbox Code Playgroud)
为了更易于使用,我尝试将代码包装在一个函数中,如下所示:
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();
}
Run Code Online (Sandbox Code Playgroud)
但是,代码在放入函数时停止运行。它抛出java.lang.ClassCastException: java.base/java.util.LinkedHashMap cannot be cast to client.rest.MyClass
. 似乎某些类型信息在此过程中的某处丢失了。
这是2个测试用例形式的完整代码:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是双重的:
回答 1。
ParameterizedTypeReference<X> typeRef = new ParameterizedTypeReference<X>() {};
Run Code Online (Sandbox Code Playgroud)
感谢最后的{}
jackson 能够X
使用反射找出运行时的内容,但是X
在编译时解决,所以如果你有MyClass
或者T
这正是它在运行时会得到的;它将无法弄清楚T
在运行时分配给什么。
出于同样的原因,如果您继续使用无函数选项,但{}
在最后删除了它,它将编译但会导致相同的错误。
回答2。
Class<T> returnType
顺便说一句,您可以ParameterizedTypeReference<T> typeRef
直接通过,而不是您从不引用 btw 。调用 post 的代码需要T
在编译时确定:
@Test
public void with_function() {
ParameterizedTypeReference<MyClass> typeRef = new ParameterizedTypeReference<>() {};
MyClass returnValue = post("some text", typeRef, "/test");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我认为您应该考虑不依赖{}
可能有问题的技巧的替代方案。
您是否尝试过ParameterizedTypeReference
的forType
?
public <T> T post(Object content, Class<T> returnType, String url){
ParameterizedTypeReference<T> typeRef = ParameterizedTypeReference.forType(returnType);
HttpEntity<Object> requestEntity = new HttpEntity<>(content);
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, typeRef);
return response.getBody();
}
Run Code Online (Sandbox Code Playgroud)
在任何情况下,这都适用于作为返回类型传递时T
喜欢的非泛型赋值;它不起作用,因为它等同于 return 。我猜在这些情况下,您需要构造并传递一个与更复杂的类型表达式相对应的不同实例。MyClass
MyClass.class
ArrayList<MyClass> list; list.getClass()
ArrayList.class
Type
归档时间: |
|
查看次数: |
2947 次 |
最近记录: |