Spring Boot opencsv

huangapple go评论81阅读模式
英文:

Spring Boot opencsv

问题

以下是翻译好的内容:

我正在尝试使用 opencsv 解析像这样的 csv 文件:

name,purchase,date
TEST,TEST,2020-10-20T00:37:53.562000000Z
TEST,TEST,2020-10-20T00:37:53.562000000Z

我尝试按照这个教程将解析后的数据添加到 Firebase 数据库:https://attacomsian.com/blog/spring-boot-upload-parse-csv-file。这是我的数据类:

public class Records {
  @CsvBindByName
  private String name;
  @CsvBindByName
  private String purchase;
  @CsvBindByName
  private Timestamp date;

  // 省略 getter 和 setter,请在需要时添加评论
}

当我解析文件时,我遇到了以下错误:

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

如何修复这个错误?我需要更改日期列的格式吗?我将日期格式从数据库中的记录复制过来,因此该格式应该是存储在数据库中的格式。

英文:

I am trying to use opencsv to parse a csv file like this:

name,purchase,date
TEST,TEST,2020-10-20T00:37:53.562000000Z
TEST,TEST,2020-10-20T00:37:53.562000000Z

I am trying to add the parsed data to a firebase database following this tutorial: https://attacomsian.com/blog/spring-boot-upload-parse-csv-file. This is my class for the data:

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
}

When I parse the file I get this error:

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

How can i fix this error? Do I need to change the format of the date column? I copied the date format from a record in the database so that format is how it should be stored in the database

答案1

得分: 2

以下是翻译好的内容:

我将 CSV 格式更改为:

name,purchase,date
TEST,TEST,2018-09-16T08:00:00
TEST,TEST,2018-09-16T08:00:00

我修改了绑定到 CSV 的类,使其如下所示:

public class CsvRecords {
  @CsvBindByName
  private String name;
  @CsvBindByName
  private String purchase;
  @CsvBindByName
  private String date;

  // 省略了为了简洁性而留下的 getter 和 setter,请在需要时进行注释
}

用于数据库中数据的 POJO 类:

public class Records {
  private String name;
  private String purchase;
  private Timestamp date;

  // 省略了为了简洁性而留下的 getter 和 setter,请在需要时进行注释
}

在控制器类中上传时,我首先将字符串转换为 LocalDateTime,然后再转换为 Timestamp,如下所示:

@PostMapping("/upload-csv-file")
public String uploadCSVFile(@RequestParam("file") MultipartFile file, Model model) {

    // 验证文件
    if (file.isEmpty()) {
        model.addAttribute("message", "请选择要上传的 CSV 文件。");
        model.addAttribute("status", false);
    } else {

        // 解析 CSV 文件以创建 `User` 对象列表
        try (Reader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {

            // 创建 CSV Bean 读取器
            CsvToBean<Records> csvToBean = new CsvToBeanBuilder(reader)
                    .withType(Records.class)
                    .withIgnoreLeadingWhiteSpace(true)
                    .build();

            // 将 `CsvToBean` 对象转换为记录列表
            List<Records> records = csvToBean.parse();

            // 在数据库中保存记录?
            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", "处理 CSV 文件时发生错误。");
            model.addAttribute("status", false);
        }
    }

    return "file-upload-status";
}

有关 firebaseServices 类(saveDetails 方法)实现的详细信息,我使用了这个 教程

英文:

I changed the csv format to:

name,purchase,date
TEST,TEST,2018-09-16T08:00:00
TEST,TEST,2018-09-16T08:00:00

I modified the class that binds to the csv to look like this:

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
}

The POJO class for the data in db:

public class Records {
private String name;
private String purchase;
private Timestamp date;
// get and setters left out for brevity pls comment if needed
}

When uploading in the controller class I then convert the string to LocalDateTime and then again to Timestamp like this:

@PostMapping(&quot;/upload-csv-file&quot;)
public String uploadCSVFile(@RequestParam(&quot;file&quot;) MultipartFile file, Model model) {
// validate file
if (file.isEmpty()) {
model.addAttribute(&quot;message&quot;, &quot;Please select a CSV file to upload.&quot;);
model.addAttribute(&quot;status&quot;, 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&lt;Records&gt; csvToBean = new CsvToBeanBuilder(reader)
.withType(Records.class)
.withIgnoreLeadingWhiteSpace(true)
.build();
// convert `CsvToBean` object to list of records
List&lt;Records&gt; records = csvToBean.parse();
// save users in DB?
for(int i = 0; i&lt;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(&quot;message&quot;, &quot;An error occurred while processing the CSV file.&quot;);
model.addAttribute(&quot;status&quot;, false);
}
}
return &quot;file-upload-status&quot;;
}

For details on the implementation of the firebaseServices class (saveDetails method) I used this tutorial

答案2

得分: 0

可以在这个情况下尝试将时间戳替换为日期吗?
就像这样进行操作:

 @CsvBindByName
 private Date date;
英文:

Could you have a try in this case that replaces the Timestamp to Date?
like follow this:

@CsvBindByName
private Date date;

答案3

得分: 0

时间戳字段对象是来自com.google.cloud.Timestamp包的一个实例。

正如@Allen建议的,您可能需要查看java.util.date,甚至是更好的选择,Java 8的时间API java.time.LocalTime,以便从ConverterPrimitiveTypes获得自动转换的支持。

英文:

The timestamp field object is an instance from com.google.cloud.Timestamp package.

As @Allen suggested, you might have to look into java.util.date or event better, the Java 8 time APIs java.time.LocalTime to get support from ConverterPrimitiveTypes to be converted automatically.

huangapple
  • 本文由 发表于 2020年10月20日 08:54:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/64437015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定