J'essaie d'utiliser opencsv pour analyser un fichier csv comme celui-ci:
Exception in thread "pool-6-thread-2" Exception in thread "pool-6-thread-1" Exception in thread "pool-6-thread-4" Exception in thread "pool-6-thread-3" java.lang.RuntimeException: com.opencsv.exceptions.CsvDataTypeMismatchException: Conversion of 2022-10-20T00:37:53.562000000Z to com.google.cloud.Timestamp failed.
at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:99)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.opencsv.exceptions.CsvDataTypeMismatchException: Conversion of 2022-10-20T00:37:53.562000000Z to com.google.cloud.Timestamp failed.
at com.opencsv.bean.ConverterPrimitiveTypes.convertToRead(ConverterPrimitiveTypes.java:128)
at com.opencsv.bean.BeanFieldSingleValue.convert(BeanFieldSingleValue.java:98)
at com.opencsv.bean.AbstractBeanField.setFieldValue(AbstractBeanField.java:180)
at com.opencsv.bean.AbstractMappingStrategy.setFieldValue(AbstractMappingStrategy.java:581)
at com.opencsv.bean.AbstractMappingStrategy.populateNewBean(AbstractMappingStrategy.java:328)
at com.opencsv.bean.concurrent.ProcessCsvLine.processLine(ProcessCsvLine.java:128)
at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:83)
... 3 more
Caused by: org.apache.commons.beanutils.ConversionException: Can't convert value '2022-10-20T00:37:53.562000000Z' to type class com.google.cloud.Timestamp
at org.apache.commons.beanutils.converters.AbstractConverter.conversionException(AbstractConverter.java:474)
at org.apache.commons.beanutils.converters.StringConverter.convertToType(StringConverter.java:96)
at org.apache.commons.beanutils.converters.AbstractConverter.convert(AbstractConverter.java:169)
at org.apache.commons.beanutils.converters.ConverterFacade.convert(ConverterFacade.java:61)
at org.apache.commons.beanutils.ConvertUtilsBean.convert(ConvertUtilsBean.java:491)
at com.opencsv.bean.ConverterPrimitiveTypes.convertToRead(ConverterPrimitiveTypes.java:118)
... 9 more
J'essaie d'ajouter les données analysées à une base de données Firebase en suivant ce tutoriel: https://attacomsian.com/blog/spring-boot-upload-parse-csv-file . Voici ma classe pour les données:
public class Records {
@CsvBindByName
private String name;
@CsvBindByName
private String purchase;
@CsvBindByName
private Timestamp date;
// get and setters left out for brevity pls comment if needed
}
Lorsque j'analyse le fichier, j'obtiens cette erreur:
name,purchase,date TEST,TEST,2020-10-20T00:37:53.562000000Z TEST,TEST,2020-10-20T00:37:53.562000000Z
Comment puis-je corriger cette erreur? Dois-je changer le format de la colonne de date? J'ai copié le format de date à partir d'un enregistrement dans la base de données afin que ce format soit la manière dont il doit être stocké dans la base de données
3 Réponses :
Pourriez-vous essayer dans ce cas qui remplace l'horodatage à ce jour? comme suivez ceci:
@CsvBindByName private Date date;
J'ai essayé cette même erreur juste qu'elle dit ne peut pas convertir en date de classe
L'objet de champ d'horodatage est une instance du package com.google.cloud.Timestamp .
Comme @Allen l'a suggéré, vous devrez peut-être mieux vous pencher sur java.util.date ou événement, les API Java 8 time java.time.LocalTime pour obtenir le soutien de ConverterPrimitiveTypes afin d'être converties automatiquement.
hm j'ai essayé cela et il obtient toujours la même erreur (sauf pour le nom de la classe)
Pouvez-vous coller la nouvelle trace de pile?
J'ai changé le format csv en:
@PostMapping("/upload-csv-file")
public String uploadCSVFile(@RequestParam("file") MultipartFile file, Model model) {
// validate file
if (file.isEmpty()) {
model.addAttribute("message", "Please select a CSV file to upload.");
model.addAttribute("status", false);
} else {
// parse CSV file to create a list of `User` objects
try (Reader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
// create csv bean reader
CsvToBean<Records> csvToBean = new CsvToBeanBuilder(reader)
.withType(Records.class)
.withIgnoreLeadingWhiteSpace(true)
.build();
// convert `CsvToBean` object to list of records
List<Records> records = csvToBean.parse();
// save users in DB?
for(int i = 0; i<records.size(); i++){
LocalDateTime localDateTime = LocalDateTime.parse(records.get(i).getDate);
Timestamp timestamp = Timestamp.valueOf(localDateTime);
Records rec = new Records(records.get(i).getName(), records.get(i).getPurchase(), timestamp)
firebaseServices.saveDetails(rec);
}
} catch (Exception ex) {
model.addAttribute("message", "An error occurred while processing the CSV file.");
model.addAttribute("status", false);
}
}
return "file-upload-status";
}
J'ai modifié la classe qui se lie au csv pour ressembler à ceci:
public class Records {
private String name;
private String purchase;
private Timestamp date;
// get and setters left out for brevity pls comment if needed
}
La classe POJO pour les données en db:
public class CsvRecords {
@CsvBindByName
private String name;
@CsvBindByName
private String purchase;
@CsvBindByName
private String date;
// get and setters left out for brevity pls comment if needed
}
Lors du téléchargement dans la classe de contrôleur, je convertis ensuite la chaîne en LocalDateTime, puis à nouveau en horodatage comme ceci:
name,purchase,date TEST,TEST,2018-09-16T08:00:00 TEST,TEST,2018-09-16T08:00:00
Pour plus de détails sur l'implémentation de la classe firebaseServices (méthode saveDetails) j'ai utilisé ce tutoriel