org.quartz.JobDataMap是否支持传入List等集合类型作为参数?
问题解答
Quartz 的 JobDataMap 支持传递集合类型参数,你遇到的 ClassCastException 本质是参数的序列化/反序列化环节出问题,并非 JobDataMap 本身不支持集合类型。
异常原因
你抛出的异常显示从JobDataMap取出的ids是String类型,常见诱因有两个:
- 你往JobDataMap存入
ids的时候,没有直接存入List对象,而是提前转成了JSON字符串或者其他格式的字符串 - 你使用了JDBCJobStore持久化作业配置,Quartz默认配置
org.quartz.jobStore.useProperties = true,会自动把JobDataMap中所有非基本类型的值转为字符串存储,取出的时候不会自动转回原对象类型。
解决方案
分不同场景处理:
场景1:使用RAMJobStore(非持久化作业)
直接在构造JobDataMap时存入List对象即可,不需要额外处理:
// 构造JobDataMap的代码示例 JobDataMap jobDataMap = new JobDataMap(); List<Integer> ids = Arrays.asList(1,2,3,4); jobDataMap.put("ids", ids); // 后续触发作业时使用该jobDataMap
取参数的代码不用修改,直接强转即可正常运行。
场景2:使用JDBCJobStore(持久化作业)
有两种可选方案:
方案A:JSON序列化转存(推荐)
将List转为JSON字符串存入,读取时再反序列化为List,可读性高,兼容性好:
存入参数时的代码:
ObjectMapper objectMapper = new ObjectMapper(); List<Integer> idsList = Arrays.asList(1,2,3,4); String idsJson = objectMapper.writeValueAsString(idsList); jobDataMap.put("ids", idsJson);
读取参数时修改代码:
public String run(JobDataMap dataMap) { String idsJson = dataMap.getString("ids"); ObjectMapper objectMapper = new ObjectMapper(); List<Integer> ids = objectMapper.readValue(idsJson, new TypeReference<List<Integer>>() {}); log.info("start the job"); // 作业业务逻辑 log.info("end Status Report job"); return "ok"; }
方案B:修改Quartz持久化配置
在quartz.properties中修改配置,关闭字符串强制转换,使用Java原生序列化存储对象:
org.quartz.jobStore.useProperties = false
注意:该方案要求存入的集合及集合内的所有元素都实现Serializable接口,且持久化到数据库的参数是二进制格式,无法直接查看内容,调试便利性较差。
内容的提问来源于stack exchange,提问作者lopushen
相关产品推荐
相关产品推荐

