Spring RestTemplate 和泛型类型 ParameterizedTypeReference 集合,如 List<T>

2022-08-31 20:29:41

抽象控制器类需要 REST 中的对象列表。在使用Spring RestTemplate时,它不会将其映射到所需的类,而是返回Linked HashMAp

 public List<T> restFindAll() {

    RestTemplate restTemplate = RestClient.build().restTemplate();
    ParameterizedTypeReference<List<T>>  parameterizedTypeReference = new ParameterizedTypeReference<List<T>>(){};
    String uri= BASE_URI +"/"+ getPath();

    ResponseEntity<List<T>> exchange = restTemplate.exchange(uri, HttpMethod.GET, null,parameterizedTypeReference);
    List<T> entities = exchange.getBody();
    // here entities are List<LinkedHashMap>
    return entities;

}

如果我使用,

ParameterizedTypeReference<List<AttributeInfo>>  parameterizedTypeReference = 
    new ParameterizedTypeReference<List<AttributeInfo>>(){};
    ResponseEntity<List<AttributeInfo>> exchange =
  restTemplate.exchange(uri, HttpMethod.GET, null,parameterizedTypeReference);

它工作正常。但不能把所有的子类都放进去,任何其他解决方案。


答案 1

我使用以下通用方法解决了这个问题:

public <T> List<T> exchangeAsList(String uri, ParameterizedTypeReference<List<T>> responseType) {
    return restTemplate.exchange(uri, HttpMethod.GET, null, responseType).getBody();
}

然后我可以打电话给:

List<MyDto> dtoList = this.exchangeAsList("http://my/url", new ParameterizedTypeReference<List<MyDto>>() {});

这确实使我的呼叫者不得不指定何时呼叫,但这意味着我不必像vels4j的答案那样保持类型的静态映射。ParameterizedTypeReference


答案 2

当 Domain 是显式类时,用于 ,效果很好,如下所示:ParameterizedTypeReferenceList<Domain>ParameterizedTypeReference

@Override
public List<Person> listAll() throws Exception {
    ResponseEntity<List<E>> response = restTemplate.exchange("http://example.com/person/", HttpMethod.GET, null,
            new ParameterizedTypeReference<List<Person>>() {});
    return response.getBody();
}

但是,如果某个方法以通用风格使用,则该列表本身应参数化。我发现的最好的方法是:listAll

public abstract class WebServiceImpl<E> implements BaseService<E> {

    private Class<E> entityClass;

    @SuppressWarnings("unchecked")
    public WebServiceImpl() {
        this.entityClass = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass())
            .getActualTypeArguments()[0];
    }


    @Override
    public List<E> listAll() throws Exception {
        ResponseEntity<List<E>> response =  restTemplate.exchange("http://example.com/person/", HttpMethod.GET, null,
                new ParameterizedTypeReference<List<E>>() {
                    @Override
                    public Type getType() {
                        Type type = super.getType();
                        if (type instanceof ParameterizedType) {
                            Type[] responseWrapperActualTypes = { entityClass };
                            ParameterizedType responseWrapperType = new ParameterizedTypeImpl(List.class,
                                    responseWrapperActualTypes, null);
                            return responseWrapperType;
                        }
                        return type;
                    }
                });
        return response.getBody();
    }
}

推荐