You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gson反序列化SQS消息时Timestamp字段解析失败

问题根源

核心问题出在嵌套的Message字段内容不是标准JSON:Timestamp的值是裸日期字符串(2023-06-18T19:36:43.219Z),但JSON规范要求字符串必须用双引号包裹。哪怕你不需要这个字段,Gson解析时也会因为JSON结构不合法直接报错,根本到不了“忽略字段”那一步。

解决思路

既然不能改原消息结构,那就先在代码里把嵌套的非标准JSON修复成合法格式,再进行反序列化,同时让Gson自动忽略不需要的字段。

具体步骤

  1. 修复JSON格式:用正则表达式给Timestamp的裸日期值加上双引号,将非标准JSON转为合法格式。
  2. 配置Gson忽略未知字段:明确指定忽略WorkId、MsgFormatVer这类POJO中未定义的字段,避免干扰反序列化。

完整代码实现

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SQSMessageParser {
    // 配置Gson:兼容宽松格式、明确忽略未知字段
    private static final Gson gson = new GsonBuilder()
            .setLenient()
            .setIgnoreUnknownProperties(true)
            .create();

    // 正则匹配Timestamp字段,精准定位需要修复的内容
    private static final Pattern TIMESTAMP_FIX_PATTERN = Pattern.compile("(Timestamp:)(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z)");

    public static <T> T parseSQSMessage(final String rawMessage, final Class<T> targetClass) {
        // 第一步:解析外层结构,拿到嵌套的非标准JSON字符串
        EventModel outerModel = gson.fromJson(rawMessage, EventModel.class);
        String nestedMsg = outerModel.getMessage();

        // 第二步:修复Timestamp字段,给日期值添加双引号
        Matcher matcher = TIMESTAMP_FIX_PATTERN.matcher(nestedMsg);
        if (matcher.find()) {
            nestedMsg = matcher.replaceFirst("$1\"$2\"");
        }

        // 第三步:反序列化修复后的合法JSON
        return gson.fromJson(nestedMsg, targetClass);
    }

    // 原POJO保持不变,添加getter/setter方便取值
    public static class EventModel {
        private String Message;

        public String getMessage() {
            return Message;
        }

        public void setMessage(String message) {
            Message = message;
        }
    }

    public static class SQSMessageBody {
        private String ObjectId;

        public String getObjectId() {
            return ObjectId;
        }

        public void setObjectId(String objectId) {
            ObjectId = objectId;
        }
    }

    // 测试示例
    public static void main(String[] args) {
        String sqsRawBody = "{\"Message\":\"{ObjectId:\\\"SomeObjectId:SomeVersion:1\\\",WorkId:\\\"12345abcdde\\\",Timestamp:2023-06-18T19:36:43.219Z,MsgFormatVer:1}\"}";
        SQSMessageBody result = parseSQSMessage(sqsRawBody, SQSMessageBody.class);
        System.out.println("解析得到的ObjectId:" + result.getObjectId());
    }
}

关键点说明

  • 正则表达式专门匹配你给出的Timestamp格式,只会修改目标字段,不会影响其他内容。
  • setLenient()用于兼容可能存在的其他轻微非标准JSON语法,配合正则修复后稳定性更高。
  • setIgnoreUnknownProperties(true)明确指定忽略未知字段,避免后续消息新增字段时出现反序列化异常。

内容的提问来源于stack exchange,提问作者Ravi Keshri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:30:43