Это кажется немного странным, вы пытаетесь поместить плоские данные в иерархию.Там вам нужно будет выполнить некоторую пользовательскую обработку, поскольку ваши ключи также не соответствуют модели, которую вы пытаетесь построить.Я привел пример того, как этого добиться, используя CSVReader
и Джексона ObjectMapper
:
public class CSVMappingTest {
static String csv = "\"id\", \"name\", \"monday_open_time\", \"monday_close_time\", \"tuesday_open_time\", \"tuesday_close_time\", \"wednesday_open_time\", \"wednesday_close_time\", \"thursday_open_time\", \"thrusday_close_time\", \"friday_open_time\", \"friday_close_time\"\n" +
"1, ABCD, 07.00.00,21.00.00, 08.00.00,22.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00\n" +
"2, ABCD, 08.00.00,21.00.00, 07.00.00,14.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00\n" +
"3, ABCD, 07.00.00,21.00.00, 10.00.00,13.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00\n" +
"4, ABCD, 09.00.00,21.00.00, 11.00.00,20.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00, 07.00.00,21.00.00";
public static void main(String[] args) throws IOException {
CSVReader reader = new CSVReader(new StringReader(csv));
ObjectMapper mapper = new ObjectMapper();
String[] keys = reader.readNext(); // headers
String[] values = reader.readNext();
while(values != null) {
Student convertValue = mapper.convertValue(csvToMap(keys, values), Student.class);
System.err.println(mapper.writeValueAsString(convertValue));
values = reader.readNext();
}
}
public static Map<String, String> csvToMap(final String[] headers, final String[] vals) {
if(headers == null || vals == null) {
throw new NullPointerException("Empty input for csv to map");
}
if(headers.length != vals.length) {
throw new IllegalArgumentException("Header and value count do not match for csv to map");
}
Map<String, String> res = new HashMap<>();
IntStream.range(0, vals.length).forEach( i -> res.put(headers[i], vals[i]));
return res;
}
public static class Student {
@JsonProperty("id")
String id;
@JsonProperty("name")
String name;
@JsonProperty
Map<String, String> studentTimings = new HashMap<>();
@JsonAnySetter
public void setTime(String key, String value) {
studentTimings.put(key, value);
}
}
}
Пояснения:
Я использую только CSVReader
для извлечения строки.
Затем я использую csvToMap
для создания сопоставления значения заголовка.
Затем я использую метод преобразования в Джексоне для автоматического создания нужного компонента.
Важный бит здесь:
@JsonAnySetter
public void setTime(String key, String value) {
studentTimings.put(key, value);
}
Это говорит Джексону, что любое свойство, не обернутое напрямую, будет отправлено сюда.Здесь вы можете обработать свое время и вручную сгруппировать его в те корзины, которые вам нужны.Я не вижу другой альтернативы, поскольку ваш плоский ввод не соответствует свойствам, которые вы пытаетесь создать.
Ни OpenCSV, ни Джексон не являются процессорами.Они не несут ответственности за преобразование ваших данных, их цель так же проста, как «найти ключ и вызвать установщика».Вы можете использовать настраиваемый сериализатор любой формы, чтобы указать ему, как создавать нужные объекты, но по умолчанию все так же просто, как и в приведенном выше утверждении.
Я уверен, что для этого тоже есть метод OpenCSV, но я его не знаю :)
Надеюсь, это поможет,
Артур
Ps Я не копировал всю вашу модель, а просто поместил значения в карту.Результат моего анализа будет, например, таким:
{
"id": "3",
"name": " ABCD",
"studentTimings": {
"friday_close_time": "21.00.00",
"friday_open_time": " 07.00.00",
"monday_close_time": "21.00.00",
"monday_open_time": " 07.00.00",
"thrusday_close_time": "21.00.00",
"thursday_open_time": " 07.00.00",
"tuesday_close_time": "13.00.00",
"tuesday_open_time": " 10.00.00",
"wednesday_close_time": "21.00.00",
"wednesday_open_time": " 07.00.00"
}
}