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

Java版AWS Lambda Cognito自定义消息触发器InvalidLambdaResponseException排查

解决Cognito自定义消息Lambda触发器的InvalidLambdaResponseException问题

我帮你排查了下这个问题,核心原因其实藏在你提供的CloudWatch日志里——输出的JSON字符串中包含了多余的换行符,导致Cognito无法正确解析Lambda的响应,才抛出了InvalidLambdaResponseException和“Unrecognizable lambda output”的错误。

先看你的日志:不管是初始输出还是调整后的后置日志,像userPoolId、userName、clientId这些字段的值后面都带有换行(比如userPoolId": "***** "),这些换行是从原始输入里带进来的,而你的代码直接把这些带换行的字段原样序列化输出了。Cognito对Lambda返回的JSON格式要求非常严格,这种隐性的换行符会破坏JSON的结构解析。

解决方案:清理字段中的换行和空白字符

你需要在处理输入JSON的时候,把所有字符串类型字段首尾的换行、空白字符都去掉,再生成响应输出。修改后的handler代码如下:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;

public class CustomMessageHandler implements RequestStreamHandler {
    private final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
        LambdaLogger logger = context.getLogger();
        JsonNode json = mapper.readTree(input);
        ObjectNode mutableJson = (ObjectNode) json;

        // 清理所有带换行的字段,去除首尾空白和换行符
        trimStringField(mutableJson, "userPoolId");
        trimStringField(mutableJson, "userName");
        trimStringField(mutableJson.with("callerContext"), "clientId");
        
        ObjectNode userAttributes = mutableJson.with("request").with("userAttributes");
        trimStringField(userAttributes, "sub");
        trimStringField(userAttributes, "given_name");
        trimStringField(userAttributes, "custom:team_id");

        // 设置自定义消息内容
        mutableJson.with("response")
                .put("smsMessage", "TEST {####}")
                .put("emailMessage", "TEST {####}")
                .put("emailSubject", "TEST subject");

        // 序列化输出,确保格式严格
        try (Writer w = new OutputStreamWriter(output, StandardCharsets.UTF_8)) {
            mapper.writeValue(w, mutableJson);
        }

        logger.log("最终输出JSON: " + mapper.writeValueAsString(mutableJson));
    }

    // 工具方法:清理ObjectNode中的字符串字段
    private void trimStringField(ObjectNode node, String fieldName) {
        if (node.has(fieldName) && node.get(fieldName).isTextual()) {
            node.put(fieldName, node.get(fieldName).asText().trim());
        }
    }
}

为什么这样能解决问题?

AWS Cognito的Lambda触发器对响应JSON的格式要求非常严格,任何不符合标准JSON规范的内容(比如字符串中未转义的换行、多余空白)都会导致解析失败。你的原始代码直接将输入中带换行的字段序列化输出,这些换行符在JSON字符串中是不允许的(除非用\n转义,但这里是实际的换行,不是转义字符),所以Cognito无法识别这个响应。

通过trim()方法去除字段值首尾的换行和空白后,输出的JSON就是严格符合规范的格式,Cognito就能正常解析了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:47:35