Получить общий тип T класса для T в новом GenericType <List <T>> () Java - PullRequest
0 голосов
/ 07 мая 2018

Я реализовал следующий класс и реализовал поисковый метод get list объекта Object для заданного типа T, используя вызов REST.

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

когда я запускаю это, я получаю следующую ошибку

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 не устанавливается в T в new GenericType<List<T>>().

как я могу установить тип от T в AmapiService<T extends Resource> до new GenericType<List<T>>()

если я определю его new GenericType<List<RFQDefinition>>() Вместо Т его работает

Ответы [ 3 ]

0 голосов
/ 07 мая 2018

Ваше использование дженериков на самом деле не служит цели здесь.

Не существует истинной универсальной реализации, поскольку ваш ответ основан на параметре, который вы предоставляете службе, которую вы потребляете (.get( new GenericType<List<T>>(){})). Параметр type не помогает в этом, потому что код вызывается реализацией jax-rs, которая не проходит статическое связывание.

Другими словами, никакой код не собирается компилироваться и запускаться для вашего класса / метода с использованием параметра:

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

Простой перевод для этого может быть: Обобщения Java не превращают его в REST API . Вы должны статически использовать тип Java для модели, которую должен возвращать ваш API (так же, как вы делаете с new GenericType<List<RFQDefinition>>()).

0 голосов
/ 07 мая 2018

Я изменил реализацию метода поиска следующим образом, теперь она работает. 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();
      }  
0 голосов
/ 07 мая 2018

Не имеет отношения к универсальному.

Сервер жалуется, что у него нет MessageBodyReader для чтения тела application/json.

Как правило, вы можете добавить Jackson как json decode / encode для вашего приложения

Читать это:

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

...