Spring RestTemplate:如何在泛型类中定义参数类型

时间:2017-01-10 14:56:36

标签: java spring generics resttemplate

我正在编写一个通用的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<DTO>)传递给单个元素(getOne)进行交换。

我应该如何将ParameterizedTypeReference传递给exchange方法,以便在运行时它知道返回List<OneActualDTO>

1 个答案:

答案 0 :(得分:1)

所以我找到了一个解决方案,即覆盖getType ParameterizedTypeReference方法返回自定义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
  }
}