在新的GenericType <list <t>&gt;()Java中将T的类通用类型添加到T.

时间:2018-05-07 17:58:21

标签: java generic-type-argument javax.ws.rs

我已经实现了以下类,并使用REST调用为给定类型的T实现了一个搜索方法获取Object列表。

    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;
   }
}

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

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

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

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

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>>()而不是它的工作

3 个答案:

答案 0 :(得分:1)

您对泛型的使用实际上并不符合此目的。

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

换句话说,没有代码可以使用参数编译和运行您的类/方法:

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

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

答案 1 :(得分:0)

它与通用无关。

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

通常,您可以为您的应用程序添加Jackson作为json decode / encode

阅读本文:

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

答案 2 :(得分:0)

我已经改变了这样的搜索方法实现,现在它正在运行。 你可以将iClass作为参数,例如: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();
      }