0

I want to parse JSON response from a GET Request. I do this usually by using a String variable to store the response and later parse this string using ArduinoJSON library like shown below:

#include <Arduino.h>
#include "OTA.h"
#include "Credentials.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char url[] = "http://date.jsontest.com/";

HTTPClient getClient;

void getRequest(String &payload)
{
  getClient.begin(url);

  int httpCode = getClient.GET();

  if (httpCode > 0)
  {
    payload = getClient.getString();
    // Serial.print("HTTP Status: ");
    // Serial.println(httpCode);
  }
  else
  {
    Serial.println("Error on HTTP request");
  }
  getClient.end();
}

void parseResponse(String &payload)
{

  StaticJsonDocument<128> doc;

  DeserializationError error = deserializeJson(doc, payload);

  if (error)
  {
    Serial.print("deserializeJson() failed: ");
    Serial.println(error.c_str());
    return;
  }

  const char *time = doc["time"]; // "03:53:25 AM"
  // unsigned long *epoch = doc["milliseconds_since_epoch"]; // 1362196405309
  const char *date = doc["date"]; // "03-02-2013"

  Serial.println(date);
}

void setup()
{
  setupOTA("ESP-N2", mySSID, myPASSWORD);

  Serial.begin(115200);
}

void loop()
{
  ArduinoOTA.handle();

  unsigned long newTime = millis();
  static unsigned long oldTime = 0;
  String payload;

  if (newTime - oldTime >= 5000)
  {
    oldTime = newTime;
    getRequest(payload);
    parseResponse(payload);
    Serial.println();
  }
}

I want to avoid using String and ArduinoJSON offician reference page mentions that it's possible to deserialize directly from input Stream e.g. wifiClient, ethernetclient or serial but I couldn't find any example showing it's usage. So I am curious to learn how to use it.

From my basic understanding of a Stream, I suppose I need define a buffer or memory location that will hold the incoming bytes and using the address of this buffer need to read data bit by bit. So do I need to do something like this:

char buffer[]= httpClient.getStream();

and then pass this buffer as input to deserialize function? or have I gotten it completely wrong?

1

1 Answer 1

2

httpClient.getStream() returns an instance of Stream that you can pass to deserializeJson(), like so:

deserializeJson(doc, httpClient.getStream());

However, by doing so, you bypass the code in HTTPClient that handles chunked transfer encoding, so you must call httpClient.useHTTP10(true) before calling GET to make sure the server won't return a chunked response.

See How to use ArduinoJson with HTTPClient?

3
  • Thanks a lot for the explanation. I am happy to learn the Stream usage. It works well but I also get [D][HTTPClient.cpp:378] disconnect(): still data in buffer (1), clean up. [D][HTTPClient.cpp:387] disconnect(): tcp stop. Since I am reading all the stream data, which data it might be referring to? Can it cause an issue like memory leakage or fragmentation?
    – Zaffresky
    Dec 27, 2021 at 14:29
  • 1
    I added ChunkedStreamReader to my StreamLib. it wraps an input Stream and decodes the chunked input: github.com/jandrassy/StreamLib/blob/…
    – Juraj
    Dec 30, 2021 at 18:34
  • I followed the approach mentioned in the docs but it seems that my GET requests fail when I use http1.0. My server is running on aws (amplify) and uses http2. What should I do in this case?
    – seddouguim
    Jun 19, 2023 at 14:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.