Skip to content

Spring Batch JSON 读写指南

⚡️ JSON 作为轻量级数据交换格式,在现代批处理中应用广泛。本教程将带您掌握 Spring Batch 中 JSON 的高效读写技巧!

一、JSON 数据处理基础

1.1 Spring Batch 支持的 JSON 格式

Spring Batch 要求 JSON 文件必须是对象数组格式,每个对象代表一个数据项:

json
[
  {
    "isin": "123",
    "quantity": 1,
    "price": 1.2,
    "customer": "foo"
  },
  {
    "isin": "456",
    "quantity": 2,
    "price": 1.4,
    "customer": "bar"
  }
]

IMPORTANT

关键约束

  • 必须是顶层数组结构
  • 每个对象应有相同的字段结构
  • 支持任意合法的 JSON 数据类型

1.2 核心组件关系

二、JSON 数据读取(JsonItemReader)

2.1 核心组件解析

JsonItemReader 通过 JsonObjectReader 实现 JSON 解析:

实现库对应类特点
JacksonJacksonJsonObjectReader性能高,功能全面
GsonGsonJsonObjectReader配置简单,轻量级

2.2 Kotlin 配置示例

kotlin
@Configuration
class BatchConfig {

    //  // 重点:创建JSON读取器
    @Bean
    fun jsonItemReader(): JsonItemReader<Trade> {
        return JsonItemReaderBuilder<Trade>()
            .jsonObjectReader(JacksonJsonObjectReader(Trade::class.java))
            .resource(ClassPathResource("trades.json"))
            .name("tradeJsonItemReader")
            .build()
    }
}

//  // 数据模型定义
data class Trade(
    val isin: String,
    val quantity: Int,
    val price: Double,
    val customer: String
)

TIP

最佳实践建议

  1. 使用 @JsonIgnoreProperties(ignoreUnknown = true) 忽略多余字段
  2. 大文件处理时启用分页读取
  3. 使用 JSON Schema 验证数据格式

常见问题

日期格式处理:JSON 中日期建议使用 ISO 格式 "2023-01-01T12:00:00Z",并在实体类添加注解:

kotlin
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
val transactionDate: Date

三、JSON 数据写入(JsonFileItemWriter)

3.1 核心组件解析

JsonFileItemWriter 通过 JsonObjectMarshaller 实现对象序列化:

实现库对应类适用场景
JacksonJacksonJsonObjectMarshaller复杂对象序列化
GsonGsonJsonObjectMarshaller简单快速序列化

3.2 Kotlin 配置示例

kotlin
@Configuration
class BatchConfig {

    //  // 重点:创建JSON写入器
    @Bean
    fun jsonFileItemWriter(): JsonFileItemWriter<Trade> {
        return JsonFileItemWriterBuilder<Trade>()
            .jsonObjectMarshaller(JacksonJsonObjectMarshaller())
            .resource(FileSystemResource("output/trades.json"))
            .name("tradeJsonFileItemWriter")
            .append(true) // 追加模式
            .build()
    }
}
输出文件美化配置(可选)
kotlin
// 配置美化输出的JSON
val mapper = ObjectMapper().apply {
    enable(SerializationFeature.INDENT_OUTPUT)
}
JsonFileItemWriterBuilder<Trade>()
    .jsonObjectMarshaller(JacksonJsonObjectMarshaller(mapper))

四、Jackson vs Gson 实现对比

kotlin
// 读取器配置
JsonItemReaderBuilder<Trade>()
    .jsonObjectReader(JacksonJsonObjectReader(Trade::class.java))

// 写入器配置
JsonFileItemWriterBuilder<Trade>()
    .jsonObjectMarshaller(JacksonJsonObjectMarshaller())

// [!code tip] // 优势:支持注解驱动,处理复杂结构更灵活
kotlin
// 读取器配置
JsonItemReaderBuilder<Trade>()
    .jsonObjectReader(GsonJsonObjectReader(Gson()))

// 写入器配置
JsonFileItemWriterBuilder<Trade>()
    .jsonObjectMarshaller(GsonJsonObjectMarshaller(Gson()))

// [!code tip] // 优势:零配置快速启动,API更简洁

NOTE

选择建议

  • 需要精细控制序列化 ➜ 选择 Jackson
  • 快速原型开发 ➜ 选择 Gson
  • 已有项目集成 ➜ 保持与现有库一致

五、最佳实践总结

5.1 性能优化技巧

5.2 错误处理方案

kotlin
@Bean
fun step(): Step {
    return stepBuilderFactory.get("jsonProcessingStep")
        .<Trade, Trade>chunk(100)
        .reader(jsonItemReader())
        .writer(jsonFileItemWriter())
        .faultTolerant()
        .skip(InvalidFormatException::class.java) // [!code error] // 格式错误跳过
        .skipLimit(10)
        .retryLimit(3)
        .retry(JsonParseException::class.java)
        .build()
}

CAUTION

关键注意事项

  1. 始终验证输入JSON结构
  2. 处理特殊字符转义(特别是用户输入字段)
  3. 考虑使用JSON Schema验证器
  4. 写入时注意文件锁定问题

六、完整流程示例

kotlin
@Configuration
class JsonBatchJob(
    private val jobBuilderFactory: JobBuilderFactory,
    private val stepBuilderFactory: StepBuilderFactory
) {

    @Bean
    fun tradeReader() = JsonItemReaderBuilder<Trade>()
        .jsonObjectReader(JacksonJsonObjectReader(Trade::class.java))
        .resource(ClassPathResource("trades.json"))
        .name("tradeReader")
        .build()

    @Bean
    fun tradeWriter() = JsonFileItemWriterBuilder<Trade>()
        .jsonObjectMarshaller(JacksonJsonObjectMarshaller())
        .resource(FileSystemResource("processed_trades.json"))
        .name("tradeWriter")
        .build()

    @Bean
    fun processStep(): Step {
        return stepBuilderFactory.get("jsonProcessing")
            .<Trade, Trade>chunk(100)
            .reader(tradeReader())
            .processor(validationProcessor()) // [!code ++] // 添加处理逻辑
            .writer(tradeWriter())
            .build()
    }

    @Bean
    fun jsonJob(): Job {
        return jobBuilderFactory.get("jsonProcessingJob")
            .start(processStep())
            .build()
    }
}

至此您已掌握 Spring Batch 中 JSON 处理的核心技能! 下一步建议:

  1. 尝试处理嵌套 JSON 对象
  2. 集成 JSON Schema 验证
  3. 实现 JSON 分片读写

⚡️ 实际应用场景:金融交易处理、日志分析、API数据同步等高频数据交换场景