Я пытаюсь использовать 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. Я хотел бы избежать этого, потому что тогда этот конвертер сообщений не будет повторно использоваться для остальной части проекта. Есть ли другие решения этой проблемы?