非标准格式JSON字符串转Java对象的映射方法求教
非常规JSON到Java对象的简便映射方案
针对键名包含>>层级分隔符的非常规JSON,无法直接通过Jackson或Gson映射到对应的ProviderInformation和PractitionerInformation实体类,以下是两种无需硬编码每个字段setter的简便方案:
方案一:利用Jackson的@JsonAnySetter动态处理字段
在顶层组合类中添加动态属性处理方法,自动拆分键名并分发到对应模块的实体类中,无需额外编写反序列化器。
代码示例
首先创建顶层组合类接收整个JSON:
@Getter @Setter public class CombinedInfo { private ProviderInformation providerInformation; private PractitionerInformation practitionerInformation; public CombinedInfo() { this.providerInformation = new ProviderInformation(); this.practitionerInformation = new PractitionerInformation(); } // 处理所有JSON键,拆分后赋值到对应模块 @JsonAnySetter public void setDynamicProperty(String key, String value) { String[] parts = key.split(">>", 2); if (parts.length != 2) { return; // 忽略格式不符的键 } String moduleName = parts[0]; String fieldName = parts[1]; // 将"Address Line 1"这类格式转为驼峰式addressLine1 String camelCaseField = toCamelCase(fieldName); try { if ("Provider Information".equals(moduleName)) { org.apache.commons.beanutils.BeanUtils.setProperty(providerInformation, camelCaseField, value); } else if ("Practitioner Information".equals(moduleName)) { org.apache.commons.beanutils.BeanUtils.setProperty(practitionerInformation, camelCaseField, value); } } catch (IllegalAccessException | InvocationTargetException e) { // 可根据需求添加日志记录或跳过无效字段 e.printStackTrace(); } } // 辅助方法:空格分隔名转驼峰式 private String toCamelCase(String input) { String[] words = input.split("\\s+"); StringBuilder sb = new StringBuilder(words[0].toLowerCase()); for (int i = 1; i < words.length; i++) { sb.append(Character.toUpperCase(words[i].charAt(0))) .append(words[i].substring(1).toLowerCase()); } return sb.toString(); } }
使用Jackson反序列化:
ObjectMapper objectMapper = new ObjectMapper(); String json = // 从CLOB读取的JSON字符串 CombinedInfo combinedInfo = objectMapper.readValue(json, CombinedInfo.class); // 直接获取目标实体类对象 ProviderInformation provider = combinedInfo.getProviderInformation(); PractitionerInformation practitioner = combinedInfo.getPractitionerInformation();
方案二:先转Map再批量赋值
不修改现有实体类,先将JSON转为Map,再拆分键名并通过BeanUtils批量赋值,代码更轻量化。
代码示例
ObjectMapper objectMapper = new ObjectMapper(); String json = // 从CLOB读取的JSON字符串 Map<String, String> jsonMap = objectMapper.readValue(json, new TypeReference<Map<String, String>>() {}); ProviderInformation provider = new ProviderInformation(); PractitionerInformation practitioner = new PractitionerInformation(); for (Map.Entry<String, String> entry : jsonMap.entrySet()) { String[] parts = entry.getKey().split(">>", 2); if (parts.length != 2) continue; String module = parts[0]; String fieldName = parts[1]; String camelCaseField = toCamelCase(fieldName); String value = entry.getValue(); try { if ("Provider Information".equals(module)) { org.apache.commons.beanutils.BeanUtils.setProperty(provider, camelCaseField, value); } else if ("Practitioner Information".equals(module)) { org.apache.commons.beanutils.BeanUtils.setProperty(practitioner, camelCaseField, value); } } catch (Exception e) { // 异常处理逻辑 } } // 辅助方法toCamelCase同方案一,此处省略
注意事项
- 依赖引入:若使用Apache BeanUtils,需添加Maven依赖:
<dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.4</version> </dependency>
若使用Spring框架,可直接用org.springframework.beans.BeanUtils,无需额外依赖。
- 字段匹配:确保
toCamelCase方法能正确转换JSON键名到实体类的驼峰字段名,比如"DOB"转为"dob"、"Address Line 2"转为"addressLine2"。 - 异常处理:实际业务中可根据需求捕获字段不存在的异常,比如跳过无效字段或记录告警日志。
内容的提问来源于stack exchange,提问作者k92
相关产品推荐
相关产品推荐

