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

Spring REST控制器接收Facebook Messenger API JSON输入显示null的问题排查

问题原因与解决方案

我之前调试Facebook Messenger Webhook时也遇到过类似的情况,咱们来一步步分析问题所在,以及对应的解决办法:

核心原因分析

你看到日志输出"Received event null",主要是因为Spring没有正确将请求体的JSON数据绑定到onWebhookEvent方法的参数上,常见的触发场景有这几个:

  1. 缺少@RequestBody注解
    Spring MVC默认不会自动将POST请求的JSON请求体绑定到方法参数上,必须显式添加@RequestBody注解,告诉框架要从请求体中读取数据并绑定到参数。如果没加这个注解,参数就会是null。

  2. 参数类型不匹配(误解了JSON的接收方式)
    你提到“原本以为它会以字符串形式传入”,这个想法本身没问题,但如果没有正确配置,Spring无法将JSON请求体转换为字符串;更常见的误区是直接用自定义对象接收,但对象结构和JSON不匹配,导致反序列化失败,最终参数为null。

  3. 请求头Content-Type不正确
    Facebook Messenger发送Webhook请求时,会自动设置Content-Type: application/json,但如果你自己测试时(比如用Postman)没设置这个头,Spring会认为请求体不是JSON格式,不会进行解析,导致参数为null。

  4. Jackson序列化配置缺失
    Spring依赖Jackson来处理JSON的序列化/反序列化,如果你的项目中缺少Jackson相关依赖(比如Spring Boot项目默认包含,但普通Spring项目需要手动引入),也会导致无法解析JSON,参数为null。

具体解决办法

1. 给方法参数添加@RequestBody注解

这是最基础也是最常见的修复方式,不管你是用字符串接收还是自定义对象接收,都需要加上这个注解:

方式一:以字符串形式接收JSON

如果只是想先打印原始JSON内容,直接用String类型参数即可:

@RestController
@RequestMapping("/webhook")
public class WebhookController {

    private static final Logger logger = LoggerFactory.getLogger(WebhookController.class);

    @PostMapping
    public ResponseEntity<String> onWebhookEvent(@RequestBody String eventBody) {
        logger.info("Received event {}", eventBody);
        // 后续可以将字符串转为JSON对象处理
        return ResponseEntity.ok("Success");
    }
}

方式二:用自定义POJO接收(推荐)

为了更方便地处理Webhook事件,建议根据Facebook Messenger的事件结构定义对应的POJO类,让Spring自动完成反序列化:

首先定义事件结构类(示例,根据实际需要补充字段):

import lombok.Data;
import java.util.List;

@Data // 用Lombok简化getter/setter,也可以手动写
public class WebhookEvent {
    private String object;
    private List<Entry> entry;

    @Data
    public static class Entry {
        private String id;
        private Long time;
        private List<Messaging> messaging;
    }

    @Data
    public static class Messaging {
        private Sender sender;
        private Recipient recipient;
        private Long timestamp;
        private Message message;
    }

    @Data
    public static class Sender {
        private String id;
    }

    @Data
    public static class Recipient {
        private String id;
    }

    @Data
    public static class Message {
        private String mid;
        private String text;
    }
}

然后在控制器中使用这个POJO:

@PostMapping
public ResponseEntity<String> onWebhookEvent(@RequestBody WebhookEvent event) {
    logger.info("Received event: object={}, entry count={}", event.getObject(), event.getEntry().size());
    // 处理具体的消息逻辑,比如获取用户发送的文本
    event.getEntry().forEach(entry -> {
        entry.getMessaging().forEach(messaging -> {
            if (messaging.getMessage() != null) {
                logger.info("User {} sent message: {}", messaging.getSender().getId(), messaging.getMessage().getText());
            }
        });
    });
    return ResponseEntity.ok("Success");
}

2. 确保请求头Content-Type正确

如果你自己测试Webhook,一定要在请求头中设置Content-Type: application/json,否则Spring不会解析请求体的JSON数据。比如用Postman测试时,在Headers标签添加这个键值对即可。

3. 确认Jackson依赖存在

如果是普通Spring项目(非Spring Boot),需要在pom.xml(Maven)或build.gradle(Gradle)中添加Jackson依赖:

  • Maven:
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- 用最新稳定版 -->
</dependency>
  • Gradle:
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'

Spring Boot项目则无需手动添加,因为spring-boot-starter-web已经包含了Jackson依赖。

测试验证

完成上述配置后,你可以用Facebook提供的Webhook测试工具,或者自己构造JSON请求发送到/webhook端点,此时日志应该能正确打印出接收到的事件内容,而不是null了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:29:29