本文讲解如何使用 gson 将原始字符串(如设备 id)构造成合法 json 对象,并与已序列化的 java 对象 json 合并,避免拼接字符串导致的格式错误和解析失败。
本文讲解如何使用 gson 将原始字符串(如设备 id)构造成合法 json 对象,并与已序列化的 java 对象 json 合并,避免拼接字符串导致的格式错误和解析失败。
在 Android 或 Java 开发中,常需将传感器、信标(iBeacon)等设备数据以 JSON 格式上报至服务端。如示例代码所示,开发者试图通过 gson.toJson(ibeacon) 获取 iBeacon 的 JSON 字符串,再手动拼接一个形如 "{deviceId : 67814f71b5bdb4d3}" 的字符串——但这种字符串拼接方式是错误的:它生成的是两个独立 JSON 片段(一个对象 + 一个非法 JSON 字符串),而非单个结构完整、字段统一的 JSON 对象,最终导致解析失败或服务端校验不通过。
✅ 正确做法是:将附加字段封装为 Java 对象,再统一交由 Gson 序列化。例如,定义一个轻量级 Gateway 类:
public class Gateway {
private String deviceId;
public Gateway(String deviceId) {
this.deviceId = deviceId;
}
// getter/setter(Lombok 可省略)
public String getDeviceId() { return deviceId; }
public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
}然后在回调中创建该对象并序列化:
@Override
public void onIBeaconDiscovered(IBeaconDevice ibeacon, IBeaconRegion region) {
Gson gson = new Gson();
// 正确:将 deviceId 封装为 Gateway 实例
Gateway gateway = new Gateway("67814f71b5bdb4d3");
// 关键:先合并数据,再统一序列化(推荐方式)
// 方案一:使用 Map 构建动态结构(无需定义类)
Map<String, Object> merged = new HashMap<>();
merged.putAll(gson.fromJson(gson.toJson(ibeacon), Map.class)); // 转为 Map
merged.put("deviceId", gateway.getDeviceId());
String finalJson = gson.toJson(merged);
Log.i("Beacon", "Merged JSON: " + finalJson);
// 发布合并后的完整 JSON
new Handler().postDelayed(() -> publish(finalJson), 5000);
}⚠️ 注意事项:
- ❌ 避免 json + json2 字符串拼接:JSON 不支持简单拼接,会破坏语法结构;
- ✅ 优先使用 Map
或自定义 POJO 合并字段,再调用 gson.toJson() 一次性序列化; - 若需深度合并(如嵌套对象冲突处理),可借助 JsonElement + JsonObject 手动构建(Gson 提供更精细控制);
- 确保字段名符合 JSON 命名规范(如使用双引号包裹 key,避免空格或特殊符号);
- 生产环境建议启用 GsonBuilder().serializeNulls() 或 setFieldNamingPolicy() 统一风格。
通过面向对象的方式组织数据,不仅保证了 JSON 合法性与可读性,也提升了代码可维护性与扩展性——新增字段只需修改 Java 类或 Map 键值,无需触碰字符串拼接逻辑。


















