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
相关产品推荐
相关产品推荐

