【问题标题】:Failing with InvalidFormatException when using date fields with jackson-dataformat-csv使用带有 jackson-dataformat-csv 的日期字段时出现 InvalidFormatException 失败
【发布时间】:2019-05-23 18:32:44
【问题描述】:

我正在尝试使用 jackson-dataformat-csv 中的 CSVMapper 实用程序来解析 CSV 文件并创建 POJO 记录以插入 mysql 数据库。

这样做时,如果日期信息作为 CSV 中要映射到 POJO 中日期字段的列之一存在,我将面临问题。

我有以下代码可以读取 CSV 文件并将其转换为 POJO。

错误.java

@Entity
@JsonIgnoreProperties(ignoreUnknown = true)
public class Bug implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    @JsonProperty
    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
    private Long Num;

    @JsonProperty("Show Bug")
    private String URL;

    @JsonProperty
    private String Subject;

    @JsonProperty
    private String Customer;

    @JsonProperty
    private String Tags;

    @JsonProperty
    private String St;

    @JsonProperty("Rep. Release")
    private String ReportedRelease;

    @JsonProperty("Reported")
    private Date reportedDate;

    @JsonProperty
    private String Sev;

    @JsonProperty
    private String Assignee;

    @JsonProperty
    private String Component;

    public Bug() {}

        /* getters and setters */

控制器代码


@PostMapping(value = "/upload", consumes = "multipart/form-data")
    public void uploadMultipart(@RequestParam("file") MultipartFile file) throws IOException {

try {

            CsvSchema bootstrap = CsvSchema.builder().setUseHeader(true)
                        .addColumn("Sl No.", CsvSchema.ColumnType.NUMBER)
                        .addColumn("Num", CsvSchema.ColumnType.NUMBER)
                        .addColumn("Show Bug", CsvSchema.ColumnType.STRING)
                        .addColumn("Customer", CsvSchema.ColumnType.STRING)
                        .addColumn("Rep. Release", CsvSchema.ColumnType.STRING)
                        .addColumn("Reported")
                        .addColumn("Component", CsvSchema.ColumnType.STRING)
                        .addColumn("Assignee", CsvSchema.ColumnType.STRING)
                        .addColumn("Sev", CsvSchema.ColumnType.STRING)
                        .addColumn("St", CsvSchema.ColumnType.STRING)
                        .addColumn("Tags", CsvSchema.ColumnType.STRING)
                        .addColumn("Subject", CsvSchema.ColumnType.STRING)
                        .build().withHeader();

            CsvMapper csvMapper = new CsvMapper();

            MappingIterator<Bug> bugInfo = 
                    csvMapper.readerFor(Bug.class).with(bootstrap).readValues(file.getInputStream());

            System.out.println("************************ Bug Information ************************");

            while(bugInfo.hasNext()) {
                Bug bugRec = bugInfo.next();
                System.out.println("Customer : " + bugRec.getCustomer());
                System.out.println("URL : " + bugRec.getURL());
            }


} catch(IOException exception) {
            throw exception;
        }
    }

这确实工作了很长一段时间,我能够在 while 循环中打印记录,然后将记录插入到 mysql 表中。

不确定代码发生了什么变化,现在我遇到了以下问题


com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.sql.Date from String value ("20-MAY-19"): not a valid representation (error: Failed to parse Date value '20-MAY-19': Can not parse date "20-MAY-19": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
 at [Source: com.fasterxml.jackson.dataformat.csv.impl.UTF8Reader@411358fc; line: 2, column: 147] (through reference chain: com.app.oracle.OMBugAnalyzerServices.entity.Bug["Reported"])
    at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:74) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1021) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:788) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:175) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.std.DateDeserializers$SqlDateDeserializer.deserialize(DateDeserializers.java:284) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.std.DateDeserializers$SqlDateDeserializer.deserialize(DateDeserializers.java:269) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:490) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:260) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.MappingIterator.nextValue(MappingIterator.java:277) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.fasterxml.jackson.databind.MappingIterator.next(MappingIterator.java:192) ~[jackson-databind-2.7.4.jar:2.7.4]
    at com.app.oracle.OMBugAnalyzerServices.controller.BugAnalyzerController.uploadMultipart(BugAnalyzerController.java:129) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_211]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_211]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_211]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_211]

【问题讨论】:

    标签: java spring-boot jackson-dataformat-csv


    【解决方案1】:

    您可以在jackson中设置格式模式,如下所示:

    @JsonFormat(pattern="yy-MM-dd")
    @JsonProperty("Reported")
    private Date reportedDate;
    

    【讨论】:

    • 非常感谢。你的建议奏效了!但我仍然想知道,当我之前从未在 POJO 类上添加此注释时,它是如何工作的。即使没有这个,它是否也能工作有什么想法吗?这只是为了我的学习目的,因为我确定我之前没有添加这个注释。
    • @svijay.aug12 不客气。也许您使用之前的日期是受支持的格式。或者以前存在杰克逊定制器。支持的格式为"yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd",如异常堆栈跟踪中所述
    【解决方案2】:

    正如下面的例外所说,

    com.fasterxml.jackson.databind.exc.InvalidFormatException: 不能 从字符串值(“20-MAY-19”)构造 java.sql.Date 的实例: 不是有效的表示(错误:无法解析日期值 “20-MAY-19”:无法解析日期“20-MAY-19”:与任何不兼容 标准格式(“yyyy-MM-dd'T'HH:mm:ss.SSSZ”, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))

    可能,您更改了以下内容。

    @JsonProperty("Reported")
    private Date reportedDate;
    

    【讨论】:

    • 嗨桑比特。谢谢你的及时回复。我在早些时候也遇到了同样的问题。那时,reportedDate 字段数据类型指向 java.util.date。当它不起作用时,我将其更改为 java.sql.Date 并开始工作。但是,目前我看到 java.util.Date 和 java.sql.Date 的异常。
    • 嗨 Sambit,我无法将类型更改为字符串。它是数据库中的一个日期字段。
    • 唯一的选择是将日期转换为具有所需格式(mm-dd-yyyy)的字符串,像这样。
    • csv-mapper 没有办法处理日期数据类型吗?因为,如果日期字段映射到数据库中的基础列并且我无法更改其类型。此外,它之前确实有效,这让我相信代码中的某些内容发生了变化,因此它现在无法正常工作。就在 3 小时前,我确实插入了 500 多条记录。现在有些事情发生了变化,我没有备份。
    • CSV 文件主要理解数字、字符串。日期取决于我们如何解释它。 CSV 不同于 excel。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    相关资源
    最近更新 更多