Arduino+4G模块HTTP请求返回-2错误,请求排查方案
问题排查与修复方案
1. HTTP请求构造顺序错误(核心触发-2错误的原因)
ArduinoHttpClient库的请求构造顺序完全不符合HTTP规范,导致请求头发送格式无效,直接触发自定义状态码-2。
错误代码逻辑:
http.beginRequest(); // 先发送请求头 http.sendHeader("Connection", "keep-alive"); // ...其他请求头 // 最后才指定请求方法和资源 http.post(resource);
HTTP协议要求请求行(包含请求方法、资源、HTTP版本)必须在所有请求头之前发送,上述顺序完全颠倒,服务器无法识别请求格式。
修复后的httpRequest函数:
void httpRequest(String json) { SerialAT.println(""); SerialAT.println(""); SerialAT.println("making POST request"); SerialAT.println(json); http.beginRequest(); // 第一步:指定请求方法和资源 http.post(resource); // 第二步:发送所有请求头 http.sendHeader("Connection", "keep-alive"); http.sendHeader("User-Agent", "ArduinoHttpClient"); http.sendHeader("Accept", "*/*"); http.sendHeader("Accept-Encoding", "gzip, deflate"); http.sendHeader("Host", server); http.sendHeader("Content-Type", "application/json"); http.sendHeader("Content-Length", String(json.length())); // 确保转为字符串类型,避免格式错误 // 检查连接状态(需在请求方法调用后) if (http.connected()) { SerialAT.println("Connected to server"); } else { SerialAT.println("Connection to server failed"); } http.beginBody(); http.print(json); http.endRequest(); int statusCode = http.responseStatusCode(); SerialAT.print("HTTP Response Code: "); SerialAT.println(statusCode); // 新增:打印服务器响应内容,方便排查后续问题 String response = http.responseBody(); SerialAT.println("Server Response: " + response); }
2. JSON构造语法错误
VibrationPackage对应的JSON存在两处语法错误,即使请求发送成功,Spring端也会返回400错误:
- 多了一个冗余双引号:
vibrationJson += "\"\"start\":\"";→ 改为vibrationJson += "\"start\":"; - 末尾多了一个闭合括号:
vibrationJson += "}"};→ 改为vibrationJson += "}"; - 补充:start/end是整数类型,不需要用双引号包裹,否则会导致Spring解析类型不匹配
修复后的VibrationPackage JSON构造代码:
} else { memcpy(&vibrationPackage, &packet, sizeof(vibrationPackage)); String vibrationJson = ""; vibrationJson += "{\"type\":\""; vibrationJson += vibrationPackage.type; vibrationJson += "\",\"key\":\""; vibrationJson += vibrationPackage.key; vibrationJson += "\",\"dataPackage\":["; for (int i = 0; i < TRANSMISSION_DATA_PACKAGE; i++) { vibrationJson += vibrationPackage.dataPackage[i]; if (i < TRANSMISSION_DATA_PACKAGE - 1) { vibrationJson += ","; } } vibrationJson += "],\"start\":"; vibrationJson += vibrationPackage.start; vibrationJson += ",\"end\":"; vibrationJson += vibrationPackage.end; vibrationJson += "}"; httpRequest(vibrationJson); }
3. 额外优化建议
- 移除无效请求头:
HTTP-Version无需手动设置,ArduinoHttpClient会自动使用HTTP/1.1构造请求行。 - GPRS连接重连逻辑:在
initGSM中,若GPRS连接失败,重置网络状态标记,触发后续重连:if (!modem.gprsConnect(apn, gprsUser, gprsPass)) { SerialAT.println("GPRS connect fail"); connectedToNetwork = false; // 重置状态,触发下次重连 return; } - Spring端验证:确认AWS安全组已开放8080端口,允许网关的公网IP访问;若后续Spring端改为实体类绑定,需确保JSON字段与实体类完全匹配。
内容的提问来源于stack exchange,提问作者user21219034
相关产品推荐
相关产品推荐

