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