Spring Boot自定义CsvMapper bean导致返回Map类型ResponseEntity报错
问题根本原因
CsvMapper是ObjectMapper的子类,你将它注册为Spring Bean后,Spring MVC会自动将其识别为HTTP消息转换的默认序列化器,替换了原本用于JSON序列化的普通ObjectMapper。
接口返回HashMap时需要序列化为JSON,但实际调用的是CsvMapper进行CSV序列化,CSV格式要求提前定义列结构,HashMap没有对应预定义的列配置,因此抛出无法识别message/timestamp等字段的错误。
返回String类型不报错的原因是Spring有专门的StringHttpMessageConverter处理字符串类型,不需要走ObjectMapper的序列化逻辑。
可用解决方案
- 方案1:不将自定义CsvMapper注册为Spring Bean
直接在CsvParserService中手动构造CsvMapper即可,避免和Spring默认的JSON序列化ObjectMapper冲突:@Slf4j @Component public final class CsvParserService { private CsvMapper csvMapper; // 直接注入DateTimeFormatter,自己构造CsvMapper public CsvParserService(DateTimeFormatter dateTimeFormatter) { JavaTimeModule javaTimeModule = new JavaTimeModule(); // 把原来configureDateTimeDeSerialization的逻辑挪过来或者调用工具方法 configureDateTimeDeSerialization(javaTimeModule, dateTimeFormatter); this.csvMapper = new CsvMapper(); csvMapper.registerModule(javaTimeModule); } // 原有parseCsvFile逻辑不变 } - 方案2:给Spring默认的ObjectMapper添加@Primary注解
如果需要保留CsvMapper作为Spring Bean,可在项目中显式声明普通ObjectMapper的Bean并添加@Primary,让Spring MVC优先使用它做JSON序列化:@Configuration public class JacksonConfig { @Bean @Primary public ObjectMapper objectMapper() { return new ObjectMapper(); } // 原有myCsvMapper的Bean定义不变 } - 方案3:显式配置Spring MVC的消息转换器
手动指定JSON序列化使用的ObjectMapper,避免被CsvMapper覆盖:@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(new ObjectMapper()); converters.add(0, jsonConverter); } }
内容的提问来源于stack exchange,提问作者Aram
相关产品推荐
相关产品推荐

