使用Jackson Dataformat库将CSV反序列化为Enum的技术问题
解决Jackson CSV反序列化到Enum类型的问题
嘿,看你的需求是把CSV第六列的HOME映射到MatchOutcome枚举对吧?我来一步步给你捋清楚怎么实现:
1. 先确认依赖
首先要确保你已经引入了Jackson CSV的依赖,如果是Maven的话,在pom.xml里加:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-csv</artifactId> <version>2.15.2</version> <!-- 换成你在用的Jackson版本 --> </dependency>
2. 定义匹配CSV的POJO类
因为CSV是按列位置来的(你的CSV没有表头),所以我们要用@CsvColumn注解指定每个字段对应的列索引(从0开始计数),第六列对应的索引就是5:
import com.fasterxml.jackson.dataformat.csv.annotation.CsvColumn; public class MatchResult { @CsvColumn(index = 0) private String homeTeam; @CsvColumn(index = 1) private String awayTeam; @CsvColumn(index = 2) private String group; @CsvColumn(index = 3) private Integer homeGoals; @CsvColumn(index = 4) private Integer awayGoals; @CsvColumn(index = 5) private MatchOutcome outcome; // 别忘了加getter、setter,或者用Lombok的@Data注解简化 public MatchOutcome getOutcome() { return outcome; } public void setOutcome(MatchOutcome outcome) { this.outcome = outcome; } // 其他字段的getter/setter... }
3. 你的Enum类调整(可选)
你的MatchOutcome枚举已经加了@JsonIgnoreProperties(ignoreUnknown = true),这个很实用,能防止CSV里出现枚举没有的取值时直接报错。而且因为CSV里的HOME和枚举的HOME完全同名,Jackson默认就能识别,不需要额外注解。不过如果后续CSV里的取值和枚举名不一致(比如小写的home),可以给枚举值加@JsonProperty指定映射关系,比如:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties(ignoreUnknown = true) public enum MatchOutcome { @JsonProperty("home") // 如果CSV里是小写home的话就加这个 HOME(3, 0), DRAW(1, 1), AWAY(0, 3), HOME_ET(1, 1), AWAY_ET(1, 1), HOME_PENS(1, 1), AWAY_PENS(1, 1); private final Integer homePoints; private final Integer awayPoints; MatchOutcome(Integer homePoints, Integer awayPoints) { this.homePoints = homePoints; this.awayPoints = awayPoints; } // 加getter方法方便后续取分数 public Integer getHomePoints() { return homePoints; } public Integer getAwayPoints() { return awayPoints; } }
4. 编写反序列化代码
接下来就是读取CSV并反序列化的逻辑,这里要注意配置CSV Schema为无表头模式:
import com.fasterxml.jackson.dataformat.csv.CsvMapper; import com.fasterxml.jackson.dataformat.csv.CsvSchema; import java.io.IOException; import java.io.StringReader; public class CsvParserDemo { public static void main(String[] args) throws IOException { // 你的CSV行内容 String csvLine = "Egypt,Uruguay,GROUP,2,0,HOME"; // 初始化CSV mapper CsvMapper csvMapper = new CsvMapper(); // 生成对应MatchResult的Schema,并且指定无表头 CsvSchema schema = csvMapper.schemaFor(MatchResult.class).withoutHeader(); // 反序列化 MatchResult matchResult = csvMapper.readerFor(MatchResult.class) .with(schema) .readValue(new StringReader(csvLine)); // 测试输出 System.out.println("比赛结果枚举值:" + matchResult.getOutcome()); System.out.println("主队获得分数:" + matchResult.getOutcome().getHomePoints()); } }
运行这段代码,就能成功把CSV里的HOME映射到MatchOutcome.HOME枚举值啦!
如果遇到反序列化失败的情况,可以先排查这几点:
- 列索引是否对应正确(第六列是index=5,别搞错了)
- CSV里的字符串和枚举名是否完全匹配(大小写、拼写都要一致)
- Jackson版本是否兼容,尽量保持核心库和dataformat版本一致
内容的提问来源于stack exchange,提问作者Clatty Cake
相关产品推荐
相关产品推荐

