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

如何用Jackson将对象字段序列化为JSON字符串适配Amazon SNS?

解决Amazon SNS推送中APNS字段需JSON字符串的Java序列化问题

针对你用Java Record定义SNS Payload时,APNS字段被序列化为嵌套对象而非JSON字符串的问题,这里有几种无需预序列化字段的简便实现方式:

方案1:自定义通用序列化器(最通用)

先写一个能把任意对象转为JSON字符串的序列化器:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;

public class JsonStringSerializer extends JsonSerializer<Object> {
    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 复用当前上下文的ObjectMapper,避免重复创建
        gen.writeString(serializers.getMapper().writeValueAsString(value));
    }
}

然后在Record的APNS字段上添加@JsonSerialize注解指定序列化器:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public record ApnsPayload(String apsAlert, Integer badge) {}

public record SnsNotificationPayload(
    @JsonSerialize(using = JsonStringSerializer.class) ApnsPayload apns,
    String defaultMessage
) {}

这样序列化时,APNS字段会自动被转为JSON字符串格式,符合SNS的要求。

方案2:内嵌序列化器(无需单独类文件)

如果不想额外创建序列化器类,可以把序列化器内嵌在Record中,尤其适合Jackson 2.12+版本:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.io.IOException;

public record ApnsPayload(String apsAlert, Integer badge) {}

public record SnsNotificationPayload(
    @JsonSerialize(using = JsonStringSerializer.class) ApnsPayload apns,
    String defaultMessage
) {
    private static class JsonStringSerializer extends JsonSerializer<Object> {
        @Override
        public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeString(serializers.getMapper().writeValueAsString(value));
        }
    }
}

方案3:利用Record的重写访问方法+@JsonRawValue

直接重写Record中APNS字段的访问方法,结合@JsonRawValue注解实现序列化:

import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public record ApnsPayload(String apsAlert, Integer badge) {}

public record SnsNotificationPayload(ApnsPayload apns, String defaultMessage) {
    // 建议复用全局ObjectMapper,比如Spring环境中注入
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @JsonRawValue
    public String apns() {
        try {
            return OBJECT_MAPPER.writeValueAsString(apns);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Failed to serialize APNS payload", e);
        }
    }
}

注意事项

  • 尽量复用ObjectMapper实例,避免每次序列化时创建新对象,提升性能;
  • 如果是Spring Boot环境,可以直接注入容器中的ObjectMapper,无需手动实例化;
  • 若APNS字段可能为null,记得在序列化器中做null值处理,避免抛出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:15:41