首页 > 解决方案 > 无法使用“CsvParser”抽象类映射解析 CSV,但可以使用 JSON 映射器

问题描述

无法将 CSV 文件解析为对象类型,

CsvMapper不适用于多态性,而 JSON 映射器适用于 jsonString。

@Getter
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
property = "type", visible = true, 
include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes({
        @Type(value = FHR.class, name = "FHR"),
        @Type(value = BHR.class, name = "BHR")})
public class PaymentBatchRecord {
    protected String type;
}

@Getter
@Setter
@JsonPropertyOrder({
//        "type",
        "transmit_id",
        "password",
        "creation_date",
        "creation_time",
        "file_format_code",
        "file_reference_code"
})
class FHR extends PaymentBatchRecord implements Serializable {
    private final static long serialVersionUID = -584359005702082280L;
    //    @JsonProperty("type")
//    private String type;
    @JsonProperty("transmit_id")
    private String transmitId;
    @JsonProperty("password")
    private String password;
    @JsonProperty("creation_date")
    private String creationDate;
    @JsonProperty("creation_time")
    private String creationTime;
    @JsonProperty("file_format_code")
    private String fileFormatCode;
    @JsonProperty("file_reference_code")
    private String fileReferenceCode;
}


@Setter
@Getter
@JsonPropertyOrder({
//        "type",
        "transaction_type",
        "merchant_id",
        "merchant_name",
        "batch_entry_description",
        "batch_reference_code",
        "batch_number"
})
class BHR extends PaymentBatchRecord implements Serializable {
    private final static long serialVersionUID = 1650905882208990490L;
    //    @JsonProperty("type")
//    private String type;
    @JsonProperty("transaction_type")
    private String transactionType;
    @JsonProperty("merchant_id")
    private String merchantId;
    @JsonProperty("merchant_name")
    private String merchantName;
    @JsonProperty("batch_entry_description")
    private String batchEntryDescription;
    @JsonProperty("batch_reference_code")
    private String batchReferenceCode;
    @JsonProperty("batch_number")
    private Integer batchNumber;
}

这是我正在尝试反序列化

        CsvMapper mapper = new CsvMapper();
        // uncomment it to run but with all the null values
// mapper.enable(CsvParser.Feature.IGNORE_TRAILING_UNMAPPABLE)
        ;
        CsvSchema sclema = mapper.schemaFor(PaymentBatchRecord.class)
                .withoutHeader();

        MappingIterator<PaymentBatchRecord> iterator = mapper
                .readerFor(PaymentBatchRecord.class)
                .with(sclema)
                .readValues(in);

        List<PaymentBatchRecord> ppojos = iterator.readAll();

这是示例 csv 输入

FHR,BILLER_1,"biller1pwd","20200224","091503","CSV","202002240915031"
BHR,"PMT","BILLER_1","BILLER 1 NAME","UTILITY BILL",,1

我得到的例外:

Exception in thread "main" com.fasterxml.jackson.dataformat.csv.CsvMappingException: Too many entries: expected at most 1 (value #1 (8 chars) "BILLER_1")
 at [Source: (com.fasterxml.jackson.dataformat.csv.impl.UTF8Reader); line: 1, column: 5]
    at com.fasterxml.jackson.dataformat.csv.CsvMappingException.from(CsvMappingException.java:28)
    at com.fasterxml.jackson.dataformat.csv.CsvParser._reportCsvMappingError(CsvParser.java:1246)
    at com.fasterxml.jackson.dataformat.csv.CsvParser._handleExtraColumn(CsvParser.java:1001)
    at com.fasterxml.jackson.dataformat.csv.CsvParser._handleNextEntry(CsvParser.java:862)
    at com.fasterxml.jackson.dataformat.csv.CsvParser.nextToken(CsvParser.java:609)
    at com.fasterxml.jackson.core.util.JsonParserSequence.switchAndReturnNext(JsonParserSequence.java:234)
    at com.fasterxml.jackson.core.util.JsonParserSequence.nextToken(JsonParserSequence.java:152)
    at com.fasterxml.jackson.core.JsonParser.nextFieldName(JsonParser.java:861)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:295)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:189)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:130)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:97)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1196)
    at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68)
    at com.fasterxml.jackson.databind.MappingIterator.nextValue(MappingIterator.java:280)
    at com.fasterxml.jackson.databind.MappingIterator.readAll(MappingIterator.java:320)
    at com.fasterxml.jackson.databind.MappingIterator.readAll(MappingIterator.java:306)

标签: javajacksonjackson-databind

解决方案


推荐阅读