不使用第三方库将API返回JSON转换为指定结构Java Map的实现问题
需求说明
调用返回JSON结构的API,无需依赖第三方JSON库,将源响应转换为指定结构的Java对象。
源API响应载荷
{ "customerId": "23408068569991", "data": [ { "nodeId": "HTS", "subscriptionId": "P_HTS_Video_1072", "subscriptionName": "HTS_Video_1053", "subscriptionDescription": "P_HTS_Video_1072", "amountCharged": 0.0, "statusCode": "0000", "adjustmentType": null, "startDate": "2021-09-28 07:41:29", "endDate": "2021-10-18 07:29:40" } ], "links": [], "statusCode": "0000", "statusMessage": "0 Success.", "transactionId": "12677889909988" }
目标转换结构
{ "customerId": "string", "transactionId": "string", "statusMessage": "string", "supportMessage": "string", "services": { "vas_hlr": { "statusCode": "2000", "data": [ { "subscriptionId": "P_HTS_Video_1072", "subscriptionProviderId": "HTC", "subscriptionName": "CHTS_Video_1053", "subscriptionDescription": "P_HTS_Video_1072", "subscriptionStatus": "Inactive", "subscriptionType": "Adhoc", "subscriptionLength": null, "registrationChannel": null, "startDate": "2019-04-30", "endDate": "2019-05-06", "subscriptionPaymentSource": "Airtime", "amountCharged": 50, "sendSMSNotification": true, "beneficiaryId": null, "auto-renew": true, "email": null, "partnerId": "String", "partnerName": "String", "lastDeductionChargeDate": "String" } ] } } }
原有代码问题点
- 类型强转错误:源响应的
data字段是数组类型,原代码直接强转为Map<String, SubscriptionService>会抛出ClassCastException - 字段映射逻辑缺失:源和目标结构存在字段名差异、格式转换需求(如日期截断为
yyyy-MM-dd),且目标结构有大量固定默认值需要填充,原代码未做对应处理 - 缺少无第三方库的JSON解析逻辑:原代码依赖提前解析好的
SubscriptionService对象,未实现原始JSON字符串到Java对象的转换逻辑
修正实现
1. 极简JSON解析工具类(无第三方依赖)
仅适配当前业务场景的JSON解析,无需兼容通用JSON格式,满足轻量化需求:
import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SimpleJsonParser { // 匹配JSON键值对 private static final Pattern KV_PATTERN = Pattern.compile("\"(\\w+)\":\\s*(\"?([^\",}\\[\\]]+)\"?|\\[|\\{)"); // 匹配数组内的JSON对象 private static final Pattern ARRAY_OBJ_PATTERN = Pattern.compile("\\{[^}]+}"); public static Map<String, Object> parse(String json) { Map<String, Object> result = new HashMap<>(); Matcher matcher = KV_PATTERN.matcher(json); while (matcher.find()) { String key = matcher.group(1); String value = matcher.group(3); String typeFlag = matcher.group(2); if ("[".equals(typeFlag)) { // 解析数组 List<Map<String, Object>> array = new ArrayList<>(); int arrayStart = json.indexOf('[', matcher.end()) + 1; int arrayEnd = json.indexOf(']', arrayStart); String arrayContent = json.substring(arrayStart, arrayEnd); Matcher objMatcher = ARRAY_OBJ_PATTERN.matcher(arrayContent); while (objMatcher.find()) { array.add(parse(objMatcher.group())); } result.put(key, array); } else if ("{".equals(typeFlag)) { // 嵌套对象,当前场景不需要可忽略 continue; } else { // 普通值处理 if ("null".equals(value)) value = null; else if (value != null && value.contains(".")) { try { result.put(key, Double.parseDouble(value)); continue; } catch (NumberFormatException ignored) {} } result.put(key, value); } } return result; } }
2. 调整转换逻辑代码
import java.util.*; public class ComvivaCustomerSubscriptions extends APIResponse { private String customerId; private String statusMessage; private String transactionId; private String supportMessage; private Map<String, SubscriptionService> services; private APIError apiError; // 新增:从原始JSON字符串构建目标对象的入口方法 public void convertFromRawJson(String rawJson) { Map<String, Object> sourceMap = SimpleJsonParser.parse(rawJson); // 填充顶层公共字段 this.customerId = (String) sourceMap.get("customerId"); this.transactionId = (String) sourceMap.get("transactionId"); this.statusMessage = (String) sourceMap.get("statusMessage"); this.supportMessage = ""; // 按业务需求填默认值 // 构建services结构 this.services = new HashMap<>(); SubscriptionService vasHlrService = new SubscriptionService(); vasHlrService.setStatusCode("2000"); // 固定默认值 List<Map<String, Object>> sourceDataList = (List<Map<String, Object>>) sourceMap.get("data"); List<Subscription> targetDataList = new ArrayList<>(); for (Map<String, Object> sourceItem : sourceDataList) { Subscription targetItem = new Subscription(); // 字段直接映射 targetItem.setSubscriptionId((String) sourceItem.get("subscriptionId")); targetItem.setSubscriptionDescription((String) sourceItem.get("subscriptionDescription")); targetItem.setAmountCharged(((Double) sourceItem.get("amountCharged")).longValue()); // 字段转换处理 targetItem.setSubscriptionProviderId((String) sourceItem.get("nodeId")); String sourceName = (String) sourceItem.get("subscriptionName"); targetItem.setSubscriptionName("C" + sourceName); // 源HTS_xxx转目标CHTS_xxx String rawStartDate = (String) sourceItem.get("startDate"); targetItem.setStartDate(rawStartDate.split(" ")[0]); // 截断日期到年月日 String rawEndDate = (String) sourceItem.get("endDate"); targetItem.setEndDate(rawEndDate.split(" ")[0]); // 填充固定默认值 targetItem.setSubscriptionStatus("Inactive"); targetItem.setSubscriptionType("Adhoc"); targetItem.setSubscriptionPaymentSource("Airtime"); targetItem.setSendSMSNotification(true); targetItem.setAutoRenew(true); // 其余null值字段无需额外处理 targetDataList.add(targetItem); } vasHlrService.setData(targetDataList); this.services.put("vas_hlr", vasHlrService); } // 原有joinServices方法按需保留,此处省略getter/setter } // 新增依赖类定义 class SubscriptionService { private String statusCode; private List<Subscription> data; // getter/setter省略 public String getStatusCode() { return statusCode; } public void setStatusCode(String statusCode) { this.statusCode = statusCode; } public List<Subscription> getData() { return data; } public void setData(List<Subscription> data) { this.data = data; } } class Subscription { private String subscriptionId; private String subscriptionProviderId; private String subscriptionName; private String subscriptionDescription; private String subscriptionStatus; private String subscriptionType; private Integer subscriptionLength; private String registrationChannel; private String startDate; private String endDate; private String subscriptionPaymentSource; private Long amountCharged; private Boolean sendSMSNotification; private String beneficiaryId; private Boolean autoRenew; private String email; private String partnerId; private String partnerName; private String lastDeductionChargeDate; // 此处省略所有getter/setter }
调用示例
public class Main { public static void main(String[] args) { String rawApiResponse = "你的源API返回的JSON字符串"; ComvivaCustomerSubscriptions target = new ComvivaCustomerSubscriptions(); target.convertFromRawJson(rawApiResponse); // 后续可直接使用target对象,或自行序列化为JSON字符串 } }
内容的提问来源于stack exchange,提问作者olanrewajufcb
相关产品推荐
相关产品推荐

