Spring RestTemplate:如何在泛型中定义参数类型class
Spring RestTemplate: how to define the parameter type in a generic class
我正在编写一个通用的 REST 客户端,用于不同类型的 DTO。
public abstract class GenericClient<DTO> {
private final Class<DTO> dtoClass;
... ctor which sets dtoClass ...
public DTO getOne(String id) {
...
URI uri = ...
ResponseEntity<DTO> exchange = getRestTemplate()
.exchange(uri, HttpMethod.GET, entity, dtoClass);
return exchange.getBody(); // works
}
public List<DTO> findAll() {
...
URI uri = ...
ResponseEntity<List<DTO>> exchange = getRestTemplate()
.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference<List<DTO>() {});
return exchange.getBody(); // fails with ClassCastException
}
}
这是由几个像这样的具体客户端实现的
public class OneActualDTOClient extends GenericClient<OneActualDTO> {
public OneActualDTOClient(){
super(OneActualDTO.class);
}
}
这会编译,getOne
方法工作正常。但是对于findAll
,在运行时,类型参数DTO是不可用的,所以exchange
方法不能反序列化传入的JSON(据我理解)
如您所见,我传递了具体的 DTO class(作为 Class<DTO>
)以用于交换单个元素(getOne
)。
我应该如何将 ParameterizedTypeReference 传递给 exchange
方法,以便在运行时它知道 return 为 List<OneActualDTO>
?
所以我找到了一个解决方案,就是覆盖 ParameterizedTypeReference
的 getType
方法返回一个定制的 ParameterizedType
像这样:
public abstract class GenericClient<DTO> {
private final Class<DTO> dtoClass;
... ctor which sets dtoClass ...
public List<DTO> findAll() {
...
URI uri = ...
ResponseEntity<List<DTO>> exchange = getRestTemplate()
.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference<List<DTO>() {
@Override
public Type getType() {
return new ParameterizedType() {
@Override
public Type getRawType() {
return List.class;
}
@Override
public Type getOwnerType() {
return null;
}
@Override
public Type[] getActualTypeArguments() {
return new Type[]{dtoClass};
}
};
});
return exchange.getBody(); // OK
}
}
我正在编写一个通用的 REST 客户端,用于不同类型的 DTO。
public abstract class GenericClient<DTO> {
private final Class<DTO> dtoClass;
... ctor which sets dtoClass ...
public DTO getOne(String id) {
...
URI uri = ...
ResponseEntity<DTO> exchange = getRestTemplate()
.exchange(uri, HttpMethod.GET, entity, dtoClass);
return exchange.getBody(); // works
}
public List<DTO> findAll() {
...
URI uri = ...
ResponseEntity<List<DTO>> exchange = getRestTemplate()
.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference<List<DTO>() {});
return exchange.getBody(); // fails with ClassCastException
}
}
这是由几个像这样的具体客户端实现的
public class OneActualDTOClient extends GenericClient<OneActualDTO> {
public OneActualDTOClient(){
super(OneActualDTO.class);
}
}
这会编译,getOne
方法工作正常。但是对于findAll
,在运行时,类型参数DTO是不可用的,所以exchange
方法不能反序列化传入的JSON(据我理解)
如您所见,我传递了具体的 DTO class(作为 Class<DTO>
)以用于交换单个元素(getOne
)。
我应该如何将 ParameterizedTypeReference 传递给 exchange
方法,以便在运行时它知道 return 为 List<OneActualDTO>
?
所以我找到了一个解决方案,就是覆盖 ParameterizedTypeReference
的 getType
方法返回一个定制的 ParameterizedType
像这样:
public abstract class GenericClient<DTO> {
private final Class<DTO> dtoClass;
... ctor which sets dtoClass ...
public List<DTO> findAll() {
...
URI uri = ...
ResponseEntity<List<DTO>> exchange = getRestTemplate()
.exchange(uri, HttpMethod.GET, entity, new ParameterizedTypeReference<List<DTO>() {
@Override
public Type getType() {
return new ParameterizedType() {
@Override
public Type getRawType() {
return List.class;
}
@Override
public Type getOwnerType() {
return null;
}
@Override
public Type[] getActualTypeArguments() {
return new Type[]{dtoClass};
}
};
});
return exchange.getBody(); // OK
}
}