AWS SNS推送返回带等号非标准JSON,如何用GSON正确解析为对象?
问题根因
你遇到的报错是因为AWS SNS下发的消息体不是标准JSON格式,默认输出的是{key=value}类toString格式,缺少JSON要求的键值双引号、键值分隔用等号而非冒号,GSON无法直接识别这类格式,所以抛出类型匹配异常。
解决方案
方案1:修改AWS SNS推送配置(优先推荐)
- 你可以在AWS SNS控制台/发送推送的服务端逻辑中,自定义发往Firebase(GCM)的消息payload,直接将需要下发的结构化数据转为标准JSON字符串后放入
data字段的对应值中。 - 调整后你客户端拿到的
params.get("message")值会变成标准JSON格式:{"message":"hello there test message"},原有GSON解析逻辑无需修改即可正常运行。 - 该方案从数据源解决格式问题,后续新增字段无需修改客户端解析逻辑,兼容性最好。
方案2:客户端兼容非标准格式(无法修改SNS配置时使用)
如果暂时无法调整SNS的发送逻辑,可以在客户端增加一层格式转换逻辑,将SNS返回的非标准格式转为标准JSON后再解析,示例代码如下:
首先新增格式转换方法:
/** * 将AWS SNS返回的{key=value,key2=value2}格式转为标准JSON字符串 * 注意:简单场景可用,若值中包含逗号、双引号等特殊字符需额外做转义处理 */ private String convertSnsFormatToJson(String snsRawStr) { // 去除首尾大括号 String content = snsRawStr.trim().replaceAll("^\\{|\\}$", ""); String[] kvPairs = content.split(","); StringBuilder jsonSb = new StringBuilder("{"); for (int i = 0; i < kvPairs.length; i++) { String kv = kvPairs[i].trim(); // 限制拆分2次,避免值中存在等号导致拆分错误 String[] keyAndValue = kv.split("=", 2); String key = keyAndValue[0].trim(); String value = keyAndValue.length > 1 ? keyAndValue[1].trim() : ""; // 拼接标准JSON键值对 jsonSb.append(String.format("\"%s\":\"%s\"", key, value)); if (i != kvPairs.length - 1) { jsonSb.append(","); } } jsonSb.append("}"); return jsonSb.toString(); }
然后修改原有解析逻辑:
@Override public void onMessageReceived(RemoteMessage remoteMessage) { try { Gson gson = new Gson(); Map<String, String> params = remoteMessage.getData(); String rawMsg = params.get("message"); // 先转格式再解析 String standardJson = convertSnsFormatToJson(rawMsg); PrintMessage message = gson.fromJson(standardJson, PrintMessage.class); // 后续业务逻辑 } catch (Exception e) { Timber.e(e); } }
注意:该兼容方案仅适用于消息值无特殊字符的简单场景,若消息中存在逗号、双引号、等号嵌套的情况,需要额外增加转义处理逻辑,还是建议优先调整SNS发送配置。
内容的提问来源于stack exchange,提问作者WHOATEMYNOODLES
相关产品推荐
相关产品推荐

