将 class 的 T 泛型类型获取到新的 GenericType<List<T>>() Java 中的 T

Get T generic type of the class to the T in the new GenericType<List<T>>() Java

我已经实施了以下 class 并使用 REST 调用为给定类型的 T 实施了搜索方法获取对象列表。

    public class AmapiService<T extends Resource> implements RestService<T> {


    @Override
    public List<T> search( MultivaluedMap<String, String> aQueryParams ) {
          MultivaluedMap<String, String> lQueryParams = aQueryParams;
          Client lClient = buildClient();

      WebTarget ltarget = lClient.target( iRestDriver.target( aApiUrl ).getUri() );

      for ( String lKey : lQueryParams.keySet() ) {
         ltarget = ltarget.queryParam( lKey, lQueryParams.getFirst( lKey ) );
      }

      List<T> lObjects = null;

      lObjects = ltarget.request( MediaType.APPLICATION_JSON ).get( new GenericType<List<T>>() {
      } );

      return lObjects;
   }
}

这是为 class 和搜索方法调用创建实例的方式。

AmapiService<RFQDefinition> RFQService =
            new AmapiService<RFQDefinition>();

List<RFQDefinition> qfq = RFQService.search( lQueryParam );

当我 运行 我收到以下错误时

May 07, 2018 1:48:14 PM org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor aroundReadFrom
SEVERE: MessageBodyReader not found for media type=application/json, type=interface java.util.List, genericType=java.util.List<T>.

这意味着 RFQDefinition 没有设置为 new GenericType<List<T>>().

中的 T

如何将 AmapiService<T extends Resource> 中的 T 类型设置为 new GenericType<List<T>>()

如果我定义它new GenericType<List<RFQDefinition>>()而不是 T 它的工作

与通用无关。

服务器抱怨它没有任何 MessageBodyReader 来读取 application/json 正文。

通常,您可以将 Jackson 添加为 json decode/encode 用于您的申请

读这个:

https://jersey.github.io/documentation/latest/media.html#json.jackson

您对泛型的使用实际上在这里没有用处。

没有真正的通用实现,因为您的响应基于您提供给您使用的服务的参数 (.get( new GenericType<List<T>>(){}))。类型参数对此没有帮助,因为代码是由 jax-rs 实现调用的,它不通过静态链接。

换句话说,没有代码会被编译,并且 运行 使用参数 class/method 来对抗你的 class/method:

//this is not a valid use-case:
List<ActualType> res = search(aQueryParams);

对此的简单翻译可以是:Java 泛型不会进入 REST API。您必须为您的 API 应该 return 的模型静态使用 Java 类型(就像您对 new GenericType<List<RFQDefinition>>() 所做的那样)。

我已经像这样更改了搜索方法实现,现在它可以工作了。 iClass 你可以把这个作为参数 eg: RFQDefinition.class

ObjectMapper mapper = new ObjectMapper();
      JavaType type = mapper.getTypeFactory().constructCollectionType( List.class, iClass );
      List<T> lObjects = null;

      JsonArray lResponse = ltarget.request( MediaType.APPLICATION_JSON ).get( JsonArray.class );
      try {
         lObjects = mapper.readValue( lResponse.toString(), type );
      } catch ( JsonParseException e ) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch ( JsonMappingException e ) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch ( IOException e ) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }