解决JSONObject.toBean() 缺少参数报错问题

本文介绍了如何使用JsonConfig过滤不需要的字段,并通过PropertyStrategyWrapper封装处理策略,以优化代码的异常处理。重点讲解了JSON对象转JavaBean时的字段选择和异常处理优化技巧。

代码:

。。。。。。1

try {
if (Map.class.isAssignableFrom(beanClass)) {
if (JSONUtils.isNull(value)) {
setProperty(bean, key, value, jsonConfig);
} else if (value instanceof JSONArray) {
setProperty(bean, key, convertPropertyValueToCollection(key, value, jsonConfig, name, classMap, List.class), jsonConfig);
} else if (!String.class.isAssignableFrom(type) && !JSONUtils.isBoolean(type) && !JSONUtils.isNumber(type) && !JSONUtils.isString(type) && !JSONFunction.class.isAssignableFrom(type)) {
Class targetClass = findTargetClass(key, classMap);
targetClass = targetClass == null ? findTargetClass(name, classMap) : targetClass;
JsonConfig jsc = jsonConfig.copy();
jsc.setRootClass(targetClass);
jsc.setClassMap(classMap);
if (targetClass != null) {
setProperty(bean, key, toBean((JSONObject)value, jsc), jsonConfig);
} else {
setProperty(bean, key, toBean((JSONObject)value), jsonConfig);
}
} else if (jsonConfig.isHandleJettisonEmptyElement() && “”.equals(value)) {
setProperty(bean, key, (Object)null, jsonConfig);
} else {
setProperty(bean, key, value, jsonConfig);
。。。。。。。2
private static void setProperty(Object bean, String key, Object value, JsonConfig jsonConfig) throws Exception {
PropertySetStrategy propertySetStrategy = jsonConfig.getPropertySetStrategy() != null ? jsonConfig.getPropertySetStrategy() : PropertySetStrategy.DEFAULT;
propertySetStrategy.setProperty(bean, key, value);
}
}

。。。。。。。。3
public void setProperty(Object bean, String key, Object value) throws JSONException {
if (bean instanceof Map) {
((Map)bean).put(key, value);
} else {
try {
PropertyUtils.setSimpleProperty(bean, key, value);
//缺少字段抛异常
//缺少字段抛异常
//缺少字段抛异常
} catch (Exception var5) {
throw new JSONException(var5);
}
}

    }

解决:1
去掉不需要的字段
JsonConfig config = new JsonConfig();
config.setIgnoreDefaultExcludes(false);
config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
config.setExcludes(new String[]{//只要设置这个数组,指定过滤哪些字段。
// “l2Interfaces”,
// “OSInstalled”,
“ipInterfaces”,
“OSRunning”,
“fileSystems”,
“balanceMan”,
“endStation”
});
//如果不需要过滤,方法可用fromObject(o)
JSONObject jsonObject = JSONObject.fromObject(o,config);
tt = (TT)JSONObject.toBean(jsonObject, TT.class);
解决:2
重新封装包装类,将异常封装
public class PropertyStrategyWrapper extends PropertySetStrategy {
private PropertySetStrategy original;

public PropertyStrategyWrapper(PropertySetStrategy original) {
    this.original = original;
}

@Override
public void setProperty(Object o, String string, Object o1) throws JSONException {
    try {
        original.setProperty(o, string, o1);
    } catch (Exception ex) {
        //ignore
    }
}

}

JsonConfig cfg = new JsonConfig();
// 设置属性包装器
cfg.setPropertySetStrategy(new PropertyStrategyWrapper(PropertySetStrategy.DEFAULT));
// 设置要转换成的JavaBean
cfg.setRootClass(TT.class);
// 转换
tt = (TT)JSONObject.toBean(obj, cfg);

https://blog.youkuaiyun.com/weixin_33866037/article/details/92383943

@PostMapping(value = "/grpCommRateQry.service", produces = "application/json;charset=utf-8") @ResponseBody public String grpCommRateQry(HttpServletRequest request, @RequestBody String jsonStr) { // 初始化RespBaseDomain EsalesResponseDomain domain = initResponseDomain(); JSONObject jsonObject = null; try { JSONObject obj = JSONObject.fromObject(jsonStr); CommRateDomain commRateDomain = (CommRateDomain) JSONObject.toBean(obj, CommRateDomain.class); String commRate = esalesInterfaceService.getCommRateInfoList(commRateDomain); if (StringUtils.isEmpty(commRate)) { setResponseDataNull(domain); } else { domain.setData(commRate); } } catch (JSONException e) { setResponseJsonError(domain); } catch (Exception e) { setResponseSystemError(domain); } finally { jsonObject = JSONObject.fromObject(domain); } return jsonObject.toString(); } public String getCommRateInfoList(CommRateDomain commRateDomain); @Override public String getCommRateInfoList(CommRateDomain commRateDomain) { Map<String, Object> paraMap = new HashMap<>(); Date salaryDate = DateUtil.getFormatDate(commRateDomain.getSalaryDate()); paraMap.put(SysConstants.CHANNEL_TYPE, commRateDomain.getChannelType()); paraMap.put("salaryDate", salaryDate); paraMap.put("productCode", commRateDomain.getProductCode()); paraMap.put("premiumYear", commRateDomain.getPremiumYear()); paraMap.put("policyYear", commRateDomain.getPolicyYear()); esalesInterfaceDao.getCommRateInfoList(paraMap); return String.valueOf(paraMap.get("commRate")); } public void getCommRateInfoList(Map<String, Object> paraMap); <parameterMap id="commRateMap" type="map"> <parameter property="commRate" jdbcType="VARCHAR" mode="OUT" /> <parameter property="channelType" jdbcType="VARCHAR" mode="IN" /> <parameter property="salaryDate" jdbcType="DATE" mode="IN" /> <parameter property="productCode" jdbcType="DATE" mode="IN" /> <parameter property="premiumYear" jdbcType="VARCHAR" mode="IN" /> <parameter property="policyYear" jdbcType="VARCHAR" mode="IN" /> <parameter property="policyId" jdbcType="VARCHAR" mode="IN" /> <parameter property="productId" jdbcType="VARCHAR" mode="IN" /> </parameterMap> <!--获取请假总天数 --> <select id="getCommRateInfoList" statementType="CALLABLE" parameterMap="commRateMap"> {? = call pkg_grp_salary_package.func_get_comm_rate(?,?,?,?,?,0,0)} </select> 传入{"channelType":"1", "salaryDate":"2023-01-01", "productCode":"T2900", "premiumYear":"5", "policyYear":"2"}时,为什么报错setResponseSystemError
最新发布
09-18
@Override @Transactional(rollbackFor = Exception.class) public Long loadmedicalstaffInfo() { try { // 请求网络 String response = executeCurlCommand(); log.info("接口返回原始数据:{}", response); // 打印接口原始响应 // 解析完整的JSON响应对象 JSONObject jsonResponse = JSONUtil.parseObj(response); // 验证响应状态 if (!jsonResponse.getInt("code").equals(0)) { String errorMsg = jsonResponse.getStr("message"); throw new RuntimeException("API返回误: " + errorMsg); } // 提取data数组 JSONArray dataArray = jsonResponse.getJSONArray("data"); log.info("接口返回的data数组长度:{}", dataArray.size()); // 打印数据总量 if (CollUtil.isEmpty(dataArray)) { log.info("data数组为空,无需处理"); return 0L; } // 转换为对象列表 List<MedicalStaffSaveReqVO> organizationList = JSON.parseArray(dataArray.toString(), MedicalStaffSaveReqVO.class); log.info("转换后的对象列表长度:{}", organizationList.size()); long savedCount = 0; for (MedicalStaffSaveReqVO item : organizationList) { log.info("开始处理记录:工号={},类型={}", item.getNumId(), item.getType()); try { // 检查是否已存在 MedicalStaffDO existingStaff = medicalStaffMapper.selectByNumId(item.getNumId()); if (existingStaff != null) { log.info("记录已存在,执行更新:工号={}", item.getNumId()); // 更新医务人员信息 updateMedicalStaff(item, existingStaff.getId()); savedCount++; } else { log.info("记录不存在,执行新增:工号={}", item.getNumId()); // 转换并保存(日期处理逻辑不变) MedicalStaffDO medicalStaffDO = BeanUtils.toBean(item, MedicalStaffDO.class); log.info("原始出生日期: {}, 类型: {}", item.getBirthDate(), item.getBirthDate() != null ? item.getBirthDate().getClass().getSimpleName() : "null"); // 处理日期字段 // 在处理日期的地方直接添加日部分"01" if (item.getBirthDate() != null) { try { String birthDate = String.valueOf(item.getBirthDate()).trim(); // 处理空或无效 if (birthDate.isEmpty() || "null".equalsIgnoreCase(birthDate)) { medicalStaffDO.setBirthDate(null); continue; } // 直接添加日部分"01"并尝试解析 if (birthDate.matches("\\d{4}-\\d{1,2}")) { // 确保月份部分是两位数字 String[] parts = birthDate.split("-"); String month = parts[1].length() == 1 ? "0" + parts[1] : parts[1]; String fullDate = parts[0] + "-" + month + "-01"; medicalStaffDO.setBirthDate(LocalDate.parse(fullDate)); log.debug("处理年月格式日期: {} -> {}", birthDate, fullDate); } else if (birthDate.matches("\\d{4}")) { // 处理仅年份的情况,添加"-01-01" String fullDate = birthDate + "-01-01"; medicalStaffDO.setBirthDate(LocalDate.parse(fullDate)); log.debug("处理年份格式日期: {} -> {}", birthDate, fullDate); } else if (birthDate.matches("\\d{4}-\\d{2}-\\d{2}")) { // 已经是完整日期格式,直接解析 medicalStaffDO.setBirthDate(LocalDate.parse(birthDate)); log.debug("处理完整日期格式: {}", birthDate); } else { // 无法识别的格式,记录警告并设为null log.warn("无法识别的日期格式: {},将设置为null", birthDate); medicalStaffDO.setBirthDate(null); } } catch (Exception e) { log.warn("日期解析失败: {},误: {}", item.getBirthDate(), e.getMessage()); medicalStaffDO.setBirthDate(null); // 解析失败时设置为null } } medicalStaffDO.setType("医师"); medicalStaffMapper.insert(medicalStaffDO); log.info("新增医务人员主表成功:ID={},工号={}", medicalStaffDO.getId(), item.getNumId()); // 保存医师明细 DoctorInfoDO doctorInfoDO = BeanUtils.toBean(item, DoctorInfoDO.class); doctorInfoDO.setId(medicalStaffDO.getId()); doctorInfoMapper.insert(doctorInfoDO); log.info("新增医师明细表成功:ID={},工号={}", doctorInfoDO.getId(), item.getNumId()); savedCount++; } } catch (Exception e) { log.error("处理记录失败:工号={},误信息={}", item.getNumId(), e.getMessage(), e); // 打印完整堆栈 } } log.info("同步完成,成功处理记录数:{}", savedCount); return savedCount; } catch (Exception e) { log.error("加载医疗人员信息失败", e); // 打印完整堆栈 throw new RuntimeException("加载医疗人员信息失败: " + e.getMessage()); } } 控制台报错:java.lang.RuntimeException: 加载医疗人员信息失败: Text '1938-09' could not be parsed at index 7
08-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值