OpenCSV + RestTemplate: типы массивов - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь использовать Spring RestTemplate для анализа удаленного файла CSV в bean-компоненте. Причина, по которой я хотел бы использовать RestTemplate, заключается в том, что он уже решает все низкоуровневые компоненты Http-соединения (главным образом, управление ресурсами), и я могу с комфортом установить тайм-аут с ним.

Итак, я написал пользовательский HttpMessageConverter, который использует OpenCSV для преобразования HttpMessage в бин CSV. Боб аннотируется соответствующей аннотацией CsvToBean OpenCSV. Проблема, однако, в том, что RestTemplate предоставляет вам именно то, что вы указали в качестве параметра класса.

restTemplate.exchange("www.exmample.com", HttpMethod.GET, null, MyDTO.class)

Выше код всегда будет возвращать точно ОДИН MyDTO. Если вы хотите иметь список MyDTO вместо этого, тогда с RestTemplate вы должны указать это вместо:

restTemplate.exchange("www.exmample.com", HttpMethod.GET, null, MyDTO[].class)

OpenCSV, однако, работает по-другому.

final CsvToBeanBuilder<MyDTO> beanBuilder = new CsvToBeanBuilder<>(new InputStreamReader(httpInputMessage.getBody()));
beanBuilder.withType(MyDTO.class); // not sure of this is needed
beanBuilder.build().parse(); // returns List<MyDTO>

Так что OpenCSV принимает единственная версия DTO без массива и его функция parse-all-all возвращает список того, что было дано. Проблема в том, что я использую OpenCSV внутри моего пользовательского HttpMessageConverter. Поэтому я вынужден работать с типом Class, который я получаю из RestTemplate:

// Inside of my class that extends HttpMessageConverter<T>

@Override
public T read(final Class<? extends T> aClass, final HttpInputMessage httpInputMessage) 
    throws IOException, HttpMessageNotReadableException {

  final CsvToBeanBuilder<T> beanBuilder = new CsvToBeanBuilder<>(new InputStreamReader(httpInputMessage.getBody()));
  beanBuilder.withType(aClass); // This throws an exception if aClass is of MyDTO[].class. 
                                // The exception states that there is no way to init the class.
  // This returns a List<Class<T>> which is already wrong. This findFirst() workaround could work but it fails earlier
  return beanBuilder.build().parse().stream().findFirst().orElse(null);
}

Единственное решение, о котором я могу подумать, - это жестко закодировать классы, которые я на самом деле хочу, в свой пользовательский HttpMessageConverter. Я хотел бы избежать этого, потому что тогда этот конвертер сообщений не будет повторно использоваться для остальной части проекта. Есть ли другие решения этой проблемы?

1 Ответ

0 голосов
/ 31 марта 2020

Вы захотите использовать ParameterizedTypeReference. Таким образом, вы можете проанализировать его как ParameterizedTypeReference>.

...