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

Spring Batch反序列化提示[Ljava.util.Date;类不受信任报错解决

问题根因

  • 报错来自Jackson 2.10+引入的多态类型反序列化信任名单安全限制,默认仅允许JDK标准类、Jackson内置类等少量类型通过多态反序列化,java.util.Date数组不在默认信任名单范围内
  • 序列化时java.util.Date被转为java.sql.Date格式,是因为默认Date序列化器会根据运行时实际的Date子类类型完成序列化,类型歧义进一步加剧了反序列化失败问题

解决方案

方案1:自定义序列化器配置信任规则(推荐)

自定义Spring Batch使用的Jackson2ExecutionContextStringSerializer,手动配置Jackson的多态类型信任规则,同时统一Date类型的序列化逻辑:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.text.SimpleDateFormat;

@Configuration
public class BatchSerializationConfig {
    @Bean
    public Jackson2ExecutionContextStringSerializer customContextSerializer() {
        // 构建多态类型信任规则
        BasicPolymorphicTypeValidator typeValidator = BasicPolymorphicTypeValidator.builder()
                // 允许java.util包下的所有类型通过校验,也可以精确指定信任类
                .allowIfBaseType("java.util.")
                // 单独添加Date数组的信任规则
                .allowIfSubType("[Ljava.util.Date;")
                .build();

        ObjectMapper objectMapper = new ObjectMapper();
        // 激活多态校验,传入自定义信任规则
        objectMapper.activateDefaultTyping(typeValidator, ObjectMapper.DefaultTyping.NON_FINAL);
        // 统一Date序列化格式,避免转为java.sql.Date格式
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        return new Jackson2ExecutionContextStringSerializer(objectMapper);
    }

    @Bean
    public JobRepository jobRepository(DataSource dataSource, PlatformTransactionManager transactionManager) throws Exception {
        JobRepositoryFactoryBean factoryBean = new JobRepositoryFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setTransactionManager(transactionManager);
        // 注入自定义序列化器
        factoryBean.setSerializer(customContextSerializer());
        factoryBean.afterPropertiesSet();
        return factoryBean.getObject();
    }
}

方案2:修改字段类型规避数组校验(可选)

将JobDetails类中的Date[] date1修改为List<Date> date1,也可以直接将日期字段转为字符串存储,反序列化后再转回Date类型,从根源规避数组类型的多态校验问题。

方案3:临时关闭类型校验(仅测试用,不推荐生产使用)

本地测试场景下可以临时关闭Jackson的多态类型校验,该配置存在安全风险,生产环境禁止使用:

// 替换原有typeValidator,允许所有类型的多态反序列化
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

额外优化

也可以直接在JobDetails类的字段上加注解,强制指定序列化器避免类型歧义:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import java.util.Date;

public class JobDetails {
    @JsonSerialize(using = DateSerializer.class)
    private Date[] date1;
    @JsonSerialize(using = DateSerializer.class)
    private Date date2;
    // 其余属性、getter/setter省略
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:36:03