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

Android向ESP32发送JSON数据为空,报EmptyInput错误求助

问题修复方案

核心问题在于ESP32端错误地使用request->arg("application/json")获取JSON数据——该方法仅用于读取URL查询参数或表单格式(如x-www-form-urlencoded)的参数,而JSON数据是存放在HTTP请求的**请求体(Body)**中的,因此无法通过这种方式读取到内容,导致解析时触发EmptyInput错误。同时Android端存在数据发送不完整的潜在问题,ESP32端也未正确返回响应。


修复1:ESP32端使用AsyncJson处理JSON请求(推荐)

你已引入AsyncJson.h,直接用库提供的处理器解析请求体中的JSON:

替换原ESP32代码中server.on("/brew_coffee", ...)的逻辑:

// 删除原来的handleBrewCoffee函数,替换为以下代码
AsyncCallbackJsonWebHandler* brewCoffeeHandler = new AsyncCallbackJsonWebHandler("/brew_coffee", [](AsyncWebServerRequest *request, JsonVariant &json) {
  if (request == nullptr) return;

  String clientIPAddress = request->client()->remoteIP().toString();
  Serial.print("\n" + clientIPAddress);
  Serial.print(" sent JSON: ");
  serializeJson(json, Serial); // 直接打印收到的完整JSON
  Serial.println();

  // 提取数据(注意类型匹配,user_id是整数)
  const char* username = json["username"];
  const char* user_ip = json["user_ip"];
  int user_id = json["user_id"];
  const char* name = json["name"];

  // 打印解析结果
  Serial.println("\nCoffee Information:");
  Serial.print("username: "); Serial.println(username);
  Serial.print("user_id: "); Serial.println(user_id);
  Serial.print("Coffee Name: "); Serial.println(name);

  // 返回响应给Android客户端
  request->send(200, "text/plain", "Coffee Received");
});
server.addHandler(brewCoffeeHandler);

修复2:ESP32端手动读取请求体(不依赖AsyncJson)

如果不想用AsyncJson库,可手动读取请求体内容:

void handleBrewCoffee(AsyncWebServerRequest *request) {
  if (request == nullptr) return;

  String clientIPAddress = request->client()->remoteIP().toString();

  // 检查是否存在请求体
  if (!request->hasParam("plain", true)) { // true表示从请求体读取
    Serial.println("\nNo body received");
    request->send(400, "text/plain", "No data received");
    return;
  }

  // 读取请求体内容
  AsyncWebParameter* param = request->getParam("plain", true);
  String recipeReceived = param->value();
  Serial.print("\n" + clientIPAddress);
  Serial.print(" sent string: ");
  Serial.println(recipeReceived);

  DynamicJsonDocument jsonDoc(16386);
  DeserializationError error = deserializeJson(jsonDoc, recipeReceived);

  if (error) {
    Serial.print("Failed to parse JSON: ");
    Serial.println(error.c_str());
    request->send(400, "text/plain", "not: " + clientIPAddress);
  } else {
    // 提取数据(注意类型匹配)
    const char* username = jsonDoc["username"];
    const char* user_ip = jsonDoc["user_ip"];
    int user_id = jsonDoc["user_id"];
    const char* name = jsonDoc["name"];

    // 打印解析结果
    Serial.println("\nCoffee Information:");
    Serial.print("username: "); Serial.println(username);
    Serial.print("user_id: "); Serial.println(user_id);
    Serial.print("Coffee Name: "); Serial.println(name);

    // 返回响应
    request->send(200, "text/plain", "Coffee Received");
  }
}

修复3:Android端确保数据完整发送

在发送JSON数据后,需刷新并关闭输出流,同时可选设置Content-Length头帮助ESP32识别数据长度:

// 替换原发送数据的代码段
OutputStream os = conn.getOutputStream();
byte[] postData = jsonParams.toString().getBytes("UTF-8");
// 可选:添加Content-Length头
conn.setRequestProperty("Content-Length", String.valueOf(postData.length));
os.write(postData);
os.flush(); // 强制发送缓冲区剩余数据
os.close(); // 关闭输出流

额外注意事项

  • 确保ESP32的AsyncWebServer和AsyncJson库为最新版本,避免版本兼容问题
  • 验证Android端发送的URL是否正确,需包含ESP32的IP地址和/brew_coffee端点
  • JSON中的user_id为整数类型,ESP32端需用int类型读取,不要用const char*

内容的提问来源于stack exchange,提问作者Lemuel Mojica Vázquez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 06:35:55