arduino ide esp8266 json从URL解码

时间:2016-06-06 18:24:22

标签: json arduino decode esp8266

我使用Arduino IDE编程esp8266。我通过WIFI加入本地网络。最后,我想下载在本地服务器上生成的内容JSON。我正在使用代码:

 #include <ESP8266WiFi.h>
    #include <ArduinoJson.h>

    const char* ssid     = "NeoRaf";
    const char* password = "password";
    const char* host = "192.168.1.8";

    void setup() {
      Serial.begin(115200);
      delay(100);

      // We start by connecting to a WiFi network

      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }

      Serial.println("");
      Serial.println("WiFi connected");  
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

      //-----------------------
      delay(5000);

      Serial.print("connecting to ");
      Serial.println(host);

      // Use WiFiClient class to create TCP connections
      WiFiClient client;
      const int httpPort = 8095;
      if (!client.connect(host, httpPort)) {
        Serial.println("connection failed");
        return;
      }

      // We now create a URI for the request
      String url = "/api";
      Serial.print("Requesting URL: ");
      Serial.println(url);

      // This will send the request to the server
      client.print("GET " + url + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "ApiCode: 8273\r\n" +
                   "Content-Type: application/json\r\n" + 
                   "Connection: close\r\n\r\n");
      delay(500);
       char c[1024];
      // Read all the lines of the reply from server and print them to Serial
       while(client.available()){
          c[0] = client.read();

      //Serial.print(c);

     Serial.print(c);
     }
       StaticJsonBuffer<200> jsonBuffer;
       JsonObject& root = jsonBuffer.parseObject(c);
      int data = root["lowVersion"];  
      Serial.println();
         Serial.print(data);

      Serial.println();
      Serial.println("closing connection");  
    }

    void loop()
    {}

结果如下:

    Connecting to NeoRaf
    ......
    WiFi connected
    IP address: 
    192.168.1.21
    connecting to 192.168.1.8
    Requesting URL: /api
    HTTP/1.1 200 OK
    Content-Length: 32
    Content-Type: application/json
    Server: Microsoft-HTTPAPI/2.0
    Access-Control-Allow-Origin: *
    Date: Mon, 06 Jun 2016 16:50:48 GMT
    Connection: close

{"lowVersion":1,"highVersion":3}
0
closing connection

这一行是JSON:

{"lowVersion":1,"highVersion":3}

所以它应该显示1并显示0。 我不知道如何摆脱标题:

HTTP/1.1 200 OK
Content-Length: 32
Content-Type: application/json
Server: Microsoft-HTTPAPI/2.0
Access-Control-Allow-Origin: *
Date: Mon, 06 Jun 2016 16:50:48 GMT

以及如何阅读JSON(lowVersion或highVersion)的内容?

3 个答案:

答案 0 :(得分:1)

您需要检测HTTP响应中何时启动有效负载。因此,当您从客户端读取数据时,您可以跳过所有HTTP标题行。顺便提一句,在JSON响应中,第一个{通常表示JSON文档的开始。

httpbin示例

请求http://httpbin.org/get收益

{
  "args": {}, 
  "headers": {
    ...
  }, 
  "origin": "XXXXXXX", 
  "url": "http://httpbin.org/get"
}

您可以像这样打印"url"字段:

String json = "";
boolean httpBody = false;
while (client.available()) {
  String line = client.readStringUntil('\r');
  if (!httpBody && line.charAt(1) == '{') {
    httpBody = true;
  }
  if (httpBody) {
    json += line;
  }
}
StaticJsonBuffer<400> jsonBuffer;
Serial.println("Got data:");
Serial.println(json);
JsonObject& root = jsonBuffer.parseObject(json);
String data = root["url"];

答案 1 :(得分:1)

HTTP标头总是以空行结束,因此您只需要阅读,直到找到两个连续的换行符。

查看ArduinoJson的示例JsonHttpClient.ino,它使用Stream::find()

// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
  // HTTP headers end with an empty line
  char endOfHeaders[] = "\r\n\r\n";

  client.setTimeout(HTTP_TIMEOUT);
  bool ok = client.find(endOfHeaders);

  if (!ok) {
    Serial.println("No response or invalid response!");
  }

  return ok;
}

答案 2 :(得分:0)

首先,为了处理HTTP请求,您可以使用RestClient库而不是编写所有低级请求。它节省了大量时间,并且不易出错。

例如,对于GET请求,您所要做的就是:

String response = "";
int statusCode = client.get("/", &response);
支持SSL的

One good such library由github用户DaKaz编写。

您可以将它用于GET请求。返回的响应将没有HTTP标头。该函数将从没有标题的服务器返回响应。

现在您可以使用bblanchin的ArduinoJson库来解码JSON对象。

可以看到详细信息here.

或者您可以执行纯字符串操作来获取值,尽管它不是建议的路径并且容易出错。