配置Java AWS Lambda使用的Objectmapper

将相本无种,男儿当自强。这篇文章主要讲述配置Java AWS Lambda使用的Objectmapper相关的知识,希望能为你提供帮助。
我正在尝试开发由SQS事件触发的AWS Lambda函数。
我使用的是spring-cloud-function-adapter-aws(版本1.0.0.RELEASE),特别是SpringBootRequestHandler。
但是,正在使用的ObjectMapper区分大小写,因此无法成功转换来自SQS的Json。
SQS发布了以下Json,特别是Record字段,我遇到了问题。

{ "Records": [ { "body": "Hello from SQS!", "receiptHandle": "MessageReceiptHandle", "md5OfBody": "7b270e59b47ff90a553787216d55d91d", "eventSourceARN": "arn:aws:sqs:eu-west-1:123456789012:MyQueue", "eventSource": "aws:sqs", "awsRegion": "eu-west-1", "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "attributes": { "ApproximateFirstReceiveTimestamp": "1523232000001", "SenderId": "123456789012", "ApproximateReceiveCount": "1", "SentTimestamp": "1523232000000" }, "messageAttributes": {} } ] }

我已经尝试过这个问题的建议,但无济于事。 Configuring ObjectMapper in Spring
在我的POJO中,我还添加了下面的注释,但它不能在Lambda之外工作。
@JsonProperty("Records") private List< SqsRecord> Records;

任何帮助将非常感激。
我的Lambda处理程序定义为:
public class SqsEventHandler extends SpringBootRequestHandler< SqsEvent, String> {}

POJO定义为:
public class SqsEvent {@JsonProperty("Records") private List< SqsRecord> records; @Data public class SqsRecord { private String body; private String receiptHandle; private String md5OfBody; private String eventSourceARN; private String eventSource; private String awsRegion; private String messageId; }

}
我希望示例消息中的Json能够被ObjectMapper读入,但字段“records”为null。
答案我们在很多AWS服务中遇到了这个问题。您必须像这样定义一个新的映射器:
SQSMixin:
private static interface SQSEventMixin { public static final String ATTRIBUTES = "attributes"; public static final String AWS_REGION = "awsRegion"; public static final String BODY = "body"; public static final String EVENT_SOURCE = "eventSource"; public static final String EVENT_SOURCE_ARN = "eventSourceARN"; public static final String MD5_OF_BOBY = "md5OfBody"; public static final String MD5_OF_MESSAGE_ATTRIBUTES = "md5OfMessageAttributes"; public static final String MESSAGE_ID = "messageId"; public static final String RECEIPT_HANDLE = "receiptHandle"; @JsonProperty(value = "https://www.songbingjia.com/android/Records") public List< ?> getRecords(); static interface MessageMixin { @JsonProperty(ATTRIBUTES) public String getAttributes(); @JsonProperty(ATTRIBUTES) public void setAttributes(String attributes); @JsonProperty(AWS_REGION) public String getAwsRegion(); @JsonProperty(AWS_REGION) public void setAwsRegion(String awsRegion); @JsonProperty(BODY) public Object getBody(); @JsonProperty(BODY) public void setBody(Object body); @JsonProperty(EVENT_SOURCE) public String getEventSource(); @JsonProperty(EVENT_SOURCE) public void setEventSource(String eventSource); @JsonProperty(EVENT_SOURCE_ARN) public String getEventSourceArn(); @JsonProperty(EVENT_SOURCE_ARN) public void setEventSourceArn(String eventSourceArn); @JsonProperty(MD5_OF_BOBY) public String getMd5OfBody(); @JsonProperty(MD5_OF_BOBY) public void setMd5OfBody(String md5OfBody); @JsonProperty(MD5_OF_MESSAGE_ATTRIBUTES) public String getMd5OfMessageAttributes(); @JsonProperty(MD5_OF_MESSAGE_ATTRIBUTES) public void setMd5OfMessageAttributes(String md5OfMessageAttributes); @JsonProperty(MESSAGE_ID) public String getMessageId(); @JsonProperty(MESSAGE_ID) public void setMessageId(String messageId); @JsonProperty(RECEIPT_HANDLE) public String getReceiptHandle(); @JsonProperty(RECEIPT_HANDLE) public void setReceiptHandle(String receiptHandle); } }

记录策略:
private static class UpperCaseRecordsPropertyNamingStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase {private static final long serialVersionUID = 1L; @Override public String translate(String propertyName) { if (propertyName.equals("records")) { return "Records"; } return propertyName; } }

日期格式化程序:
private static final DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTime() .withZone(new FixedDateTimeZone("GMT", "GMT", 0, 0)); private static class DateTimeMapperModule extends SimpleModule {private static final long serialVersionUID = 1L; public DateTimeMapperModule() { super("DateTimeMapperModule"); super.addSerializer(DateTime.class, new DateTimeSerializer()); super.addDeserializer(DateTime.class, new DateTimeDeserializer()); } }private static class DateTimeSerializer extends JsonSerializer< DateTime> {@Override public void serialize(DateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException {gen.writeString(dateTimeFormatter.print(value)); } }private static class DateTimeDeserializer extends JsonDeserializer< DateTime> {@Override public DateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {return dateTimeFormatter.parseDateTime(parser.getText()); } }

【配置Java AWS Lambda使用的Objectmapper】并声明你的映射器:
ObjectMapper mapper = new ObjectMapper(); mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); mapper.setPropertyNamingStrategy(new UpperCaseRecordsPropertyNamingStrategy()); mapper.registerModule(new DateTimeMapperModule()); mapper.addMixIn(SQSMessage.class, SQSEventMixin.MessageMixin.class); SQSEvent request = mapper.convertValue(inputObject, SQSEvent.class);

另一答案我以更简单的方式解决了这个问题。
引用https://docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-stream.html和具体的
如果Lambda的序列化方法不能满足您的需求,您可以使用字节流实现
我现在直接使用SpringBootStreamHandler,我在Spring Configuration类中创建了一个带有我所需配置选项的ObjectMapper实例:
@Bean public ObjectMapper objectMapper() { final ObjectMapper mapper = new ObjectMapper(); mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return mapper; }


    推荐阅读