Получение ресурса REST в виде списка <T>с Джерси - PullRequest
17 голосов
/ 12 августа 2011

Я пытаюсь написать универсальную функцию на Джерси, которую можно использовать для получения списка объектов того же типа через REST.Я основал это на информации, найденной на этом форуме: ссылка

@Override
public <T> List<T> fetchResourceAsList(String url) {
  ClientConfig cc = new DefaultClientConfig();
  Client c = Client.create(cc);
  if (userName!=null && password!=null) {
    c.addFilter(new HTTPBasicAuthFilter(userName, password)); 
  }
  WebResource resource = c.resource(url);
  return resource.get(new GenericType<List<T>>() {});
}

Однако это не работает.Если я пытаюсь выполнить его, я получаю следующую ошибку: SEVERE: A message body reader for Java class java.util.List, and Java type java.util.List<T>, and MIME media type application/xml was not found.

Однако, если я пишу эту функцию без шаблонов (заменяя T на фактическое имя класса), он просто отлично работает.Конечно, таким образом функция теряет смысл.

Есть ли способ это исправить?

Ответы [ 3 ]

24 голосов
/ 26 апреля 2013

Я нашел решение https://java.net/projects/jersey/lists/users/archive/2011-08/message/37

public <T> List<T> getAll(final Class<T> clazz) {

    ParameterizedType parameterizedGenericType = new ParameterizedType() {
        public Type[] getActualTypeArguments() {
            return new Type[] { clazz };
        }

        public Type getRawType() {
            return List.class;
        }

        public Type getOwnerType() {
            return List.class;
        }
    };

    GenericType<List<T>> genericType = new GenericType<List<T>>(
            parameterizedGenericType) {
    };

    return service.path(Path.ROOT).path(clazz.getSimpleName())
            .accept(MediaType.APPLICATION_XML).get(genericType);
}
6 голосов
/ 12 августа 2011

См. Класс трикотажа GenericType, который также может вам помочь

Unmarshaller должен знать, какой тип объекта существует, прежде чем он сможет демонтировать возвращаемый контент. Поскольку обобщенная информация недоступна во время выполнения, то, что вы просите, невозможно. Он не может разобрать то, о чем ничего не знает.

лучшее, что вы можете сделать, это;

public <T> List<T> fetchResourceAsList(Class<?> beanClass, String url) {
    ...

   if(beanCLass.equals(MyBean.class)){
      return resource.get(new GenericType<List<MyBean>>()
   }else if(...){
      ...
   }...
}

или с общими предупреждениями (я не уверен, что это сработает)

public List fetchResourceAsList(String url) {
    ...
      return resource.get(new GenericType<List<Serializable>>()
}
3 голосов
/ 05 июня 2014

Расширяя user2323189, вы можете использовать Collection вместо List.class, чтобы вы могли сериализовать все типы расширяющих Collection.Я создаю простой метод получения в своем базовом клиентском классе и могу просто использовать его для извлечения любого типа коллекции.В моем конструкторе не указана переменная clazz, поэтому она не является аргументом.Возможно, вы могли бы превратить это в статический метод и использовать сигнатуру GenericType> с параметром для класса, чтобы сделать его еще более универсальным.

public GenericType<Collection<T>> getParameterizedCollectionType() {
        ParameterizedType parameterizedGenericType = new ParameterizedType() {
            public Type[] getActualTypeArguments() {
                return new Type[] { clazz };
            }

            public Type getRawType() {
                return Collection.class;
            }

            public Type getOwnerType() {
                return Collection.class;
            }
        };
        return new GenericType<Collection<T>>(parameterizedGenericType){};
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...