You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Open CSV实现单CSV列到多DTO字段的映射?

如何用注解式CSV库实现单CSV列到多个DTO字段的映射反序列化?

当前实现代码

MyDto类

public class MyDto {
    @CsvBindByName(column = "AFBP")
    String placeholderA;
    @CsvBindByNames({
            @CsvBindByName(column = "ABCD"),
            @CsvBindByName(column = "AFEL")
    })
    String placeholderB;

    @CsvBindByNames({
            @CsvBindByName(column = "ABCD"),
            @CsvBindByName(column = "ALTM")
    })
    String placeholderC;

    @Override
    public String toString() {
        return "placeholder A = " + placeholderA + ", placeholderB = " + placeholderB + ", placeholderC = " + placeholderC;
    }
}

待反序列化的CSV内容

var csv = "AFBP,ABCD\nthis is A,this is B and C";

实际反序列化结果

placeholder A = this is A, placeholderB = null, placeholderC = this is B and C

期望结果

placeholder A = this is A, placeholderB = this is B and C, placeholderC = this is B and C

问题

能否通过OpenCSV或其他支持注解的CSV库,实现单CSV列到多个DTO字段的映射反序列化?


解决方案

针对OpenCSV的解决方法

OpenCSV默认的@CsvBindByNames注解处理多字段映射同一列时,只会给其中一个字段赋值,无法自动同步到多个字段。可以通过以下方式实现需求:

  1. 利用Setter方法同步值
    放弃在多个字段上直接绑定注解,转而通过一个绑定目标列的Setter方法,同时给多个字段赋值:

    public class MyDto {
        @CsvBindByName(column = "AFBP")
        String placeholderA;
        
        String placeholderB;
        String placeholderC;
    
        @CsvBindByName(column = "ABCD")
        public void setCommonValue(String value) {
            this.placeholderB = value;
            this.placeholderC = value;
        }
    
        @Override
        public String toString() {
            return "placeholder A = " + placeholderA + ", placeholderB = " + placeholderB + ", placeholderC = " + placeholderC;
        }
    }
    

    这种方式绕过注解的限制,通过手动赋值实现多字段同步。

  2. 自定义MappingStrategy
    继承HeaderColumnNameMappingStrategy,重写populateBean方法,在完成默认映射逻辑后,主动将指定列的值赋值给需要同步的多个字段。

其他注解式CSV库的替代方案

如果不想修改OpenCSV的使用逻辑,可以尝试Jackson CSV,它支持将同一列名映射到多个字段:

public class MyDto {
    @JsonProperty("AFBP")
    String placeholderA;
    
    @JsonProperty("ABCD")
    String placeholderB;
    
    @JsonProperty("ABCD")
    String placeholderC;

    @Override
    public String toString() {
        return "placeholder A = " + placeholderA + ", placeholderB = " + placeholderB + ", placeholderC = " + placeholderC;
    }
}

使用Jackson CSV的CsvMapper执行反序列化时,会自动将ABCD列的值同时赋值给placeholderB和placeholderC。


内容的提问来源于stack exchange,提问作者michal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:10:26