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

请问该序列化格式名称是什么?如何转换为POJO?

如何将非标准类JSON格式的SQS消息解析为POJO

嘿,我完全懂你的困扰——这种键名不带引号的类JSON格式确实够让人头疼的,既不是标准JSON也不是ION,直接用常规的JSON解析工具根本没法转成POJO,想提取Body里你真正关心的Message部分都无从下手。不过别担心,咱们有两种靠谱的解决方案可以试试:

先理清楚你的场景

你正在通过JMS异步接收SNS发布到SQS的消息,用onMessage方法拿到的消息文本是类似这样的非标准格式:

示例非标准格式

{ ExampleKey1: ExampleValue1, ExampleKey2: ExampleValue2, ExampleObjectKey: { "ObjectKey" : "ObjectValue" } }

你实际收到的消息格式

{MessageId: 123-123-123,ReceiptHandle: BigTextWithCharactersLike+and/andNumbers123,MD5OfBody: AlphaNumberic123,Body: { "Type" : "Notification", "MessageId" : "uuid-uuid-uuid-uuid", "TopicArn" : "arn:aws:sns:us-west-2:someARN", "Message" : "{\"this\":\"is\",\"the\":\"part\",\"i\":\"am\",\"interested\":\"in\"}", "Timestamp" : "timestamp", "SignatureVersion" : "1", "Signature" : "alphanumeric+charatersLike+and/and==", "SigningCertURL" : "https://an-sns-url", "UnsubscribeURL" : "https://an-sns-url" },Attributes: {},MessageAttributes: {}}

获取消息的代码

public void onMessage(Message message) { 
    try { 
        // Cast the received message as TextMessage and print the text to screen. 
        System.out.println("Received: " + ((TextMessage) message).getText()); 
    } catch (JMSException e) { 
        e.printStackTrace(); 
    } 
}

两种解决方案推荐

方案一:预处理字符串为标准JSON

这种格式的核心问题是键名没有被双引号包裹,我们可以用正则表达式把所有键名加上双引号,转换成标准JSON后再用常规解析工具处理:

  • 编写正则替换逻辑,匹配所有符合键名:格式的部分,替换为"键名":。注意要避免替换到值里的内容(比如Body中已经带引号的字段),可以用这个正则:(\w+)(?=:)
  • 用Jackson或Gson等JSON库解析处理后的字符串到自定义POJO。

示例代码(Java + Jackson):

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.regex.Pattern;

public class MessageParser {
    private static final Pattern KEY_PATTERN = Pattern.compile("(\\w+)(?=:)");

    public void parseMessage(TextMessage textMessage) throws Exception {
        String rawMessage = textMessage.getText();
        // 预处理:给所有键名加上双引号,转成标准JSON
        String standardJson = KEY_PATTERN.matcher(rawMessage).replaceAll("\"$1\"");
        
        // 解析到自定义的SQS消息POJO
        ObjectMapper objectMapper = new ObjectMapper();
        SqsMessage sqsMessage = objectMapper.readValue(standardJson, SqsMessage.class);
        
        // 提取Body中的Notification内容,再解析里面的Message字段
        Notification notification = objectMapper.readValue(sqsMessage.getBody(), Notification.class);
        String innerMessageJson = notification.getMessage();
        // 解析你真正关心的内容到目标POJO
        YourTargetPojo targetData = objectMapper.readValue(innerMessageJson, YourTargetPojo.class);
    }
}

// 自定义SQS消息POJO
class SqsMessage {
    private String MessageId;
    private String ReceiptHandle;
    private String MD5OfBody;
    private String Body;
    // 其他对应字段的getter/setter方法
}

// SNS Notification对应的POJO
class Notification {
    private String Type;
    private String MessageId;
    private String TopicArn;
    private String Message;
    // 其他对应字段的getter/setter方法
}

// 你真正关心的内容对应的POJO
class YourTargetPojo {
    private String this;
    private String is;
    private String the;
    // 对应字段的getter/setter方法
}

方案二:直接使用AWS SDK的封装类

你提到这个消息对应AWS SDK中封装的Message类,那其实完全可以跳过手动解析的麻烦,直接用AWS SDK的SQS客户端来接收消息——SDK会自动帮你把消息解析成现成的Message对象,不用自己处理非标准格式:

示例代码(AWS SDK v2):

import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
import software.amazon.awssdk.services.sqs.model.Message;
import com.fasterxml.jackson.databind.ObjectMapper;

public class SqsAsyncReceiver {
    public void receiveMessages() {
        // 初始化SQS客户端
        SqsClient sqsClient = SqsClient.create();
        String yourQueueUrl = "你的队列URL";
        
        // 构建接收消息的请求
        ReceiveMessageRequest request = ReceiveMessageRequest.builder()
                .queueUrl(yourQueueUrl)
                .maxNumberOfMessages(1)
                .build();
                
        // 接收并解析消息
        for (Message sqsMessage : sqsClient.receiveMessage(request).messages()) {
            // 获取SNS推送的Notification内容(已经是标准JSON字符串)
            String notificationJson = sqsMessage.body();
            
            // 解析Notification到对应POJO
            ObjectMapper objectMapper = new ObjectMapper();
            Notification notification = objectMapper.readValue(notificationJson, Notification.class);
            
            // 解析你关心的Message部分到目标POJO
            YourTargetPojo targetData = objectMapper.readValue(notification.getMessage(), YourTargetPojo.class);
        }
    }
}

这个方案更稳妥,因为SDK已经处理了所有格式细节,不用自己写正则处理非标准格式,不容易出错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:03:08