* Added handler for correct JSON deserialization (even with multiple body data writes), addresses #195 * Fixed typo * Added JSON handler example to readme * Moved Json Handler uri parameter to constructor * Use request->_tempObject for JSON char data buffer * Moved onRequest to constructor in JSON async handler
This commit is contained in:
parent
fc66fae6a9
commit
d7399a7664
15
README.md
15
README.md
|
@ -30,6 +30,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht
|
|||
- [GET, POST and FILE parameters](#get-post-and-file-parameters)
|
||||
- [FILE Upload handling](#file-upload-handling)
|
||||
- [Body data handling](#body-data-handling)
|
||||
- [JSON body handling with ArduinoJson](#json-body-handling-with-arduinojson)
|
||||
- [Responses](#responses)
|
||||
- [Redirect to another URL](#redirect-to-another-url)
|
||||
- [Basic response with HTTP Code](#basic-response-with-http-code)
|
||||
|
@ -313,6 +314,20 @@ void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_
|
|||
}
|
||||
}
|
||||
```
|
||||
If needed, the `_tempObject` field on the request can be used to store a pointer to temporary data (e.g. from the body) associated with the request. If assigned, the pointer will automatically be freed along with the request.
|
||||
|
||||
### JSON body handling with ArduinoJson
|
||||
Endpoints which consume JSON can use a special handler to get ready to use JSON data in the request callback:
|
||||
```cpp
|
||||
#include "AsyncJson.h"
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/endpoint", [](AsyncWebServerRequest *request, JsonVariant &json) {
|
||||
JsonObject& jsonObj = json.as<JsonObject>();
|
||||
// ...
|
||||
});
|
||||
server.addHandler(handler);
|
||||
```
|
||||
|
||||
## Responses
|
||||
### Redirect to another URL
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// ESPasyncJson.h
|
||||
// AsyncJson.h
|
||||
/*
|
||||
Async Response to use with arduinoJson and asyncwebserver
|
||||
Async Response to use with ArduinoJson and AsyncWebServer
|
||||
Written by Andrew Melvin (SticilFace) with help from me-no-dev and BBlanchon.
|
||||
|
||||
example of callback in use
|
||||
Example of callback in use
|
||||
|
||||
server.on("/json", HTTP_ANY, [](AsyncWebServerRequest * request) {
|
||||
|
||||
|
@ -17,11 +17,27 @@
|
|||
request->send(response);
|
||||
});
|
||||
|
||||
--------------------
|
||||
|
||||
Async Request to use with ArduinoJson and AsyncWebServer
|
||||
Written by Arsène von Wyss (avonwyss)
|
||||
|
||||
Example
|
||||
|
||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/endpoint");
|
||||
handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) {
|
||||
JsonObject& jsonObj = json.as<JsonObject>();
|
||||
// ...
|
||||
});
|
||||
server.addHandler(handler);
|
||||
|
||||
*/
|
||||
#ifndef ASYNC_JSON_H_
|
||||
#define ASYNC_JSON_H_
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
const char* JSON_MIMETYPE = "application/json";
|
||||
|
||||
/*
|
||||
* Json Response
|
||||
* */
|
||||
|
@ -57,7 +73,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
|||
public:
|
||||
AsyncJsonResponse(bool isArray=false): _isValid{false} {
|
||||
_code = 200;
|
||||
_contentType = "application/json";
|
||||
_contentType = JSON_MIMETYPE;
|
||||
if(isArray)
|
||||
_root = _jsonBuffer.createArray();
|
||||
else
|
||||
|
@ -80,4 +96,68 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
|||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(AsyncWebServerRequest *request, JsonVariant &json)> ArJsonRequestHandlerFunction;
|
||||
|
||||
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
|
||||
private:
|
||||
protected:
|
||||
const String _uri;
|
||||
WebRequestMethodComposite _method;
|
||||
ArJsonRequestHandlerFunction _onRequest;
|
||||
int _contentLength;
|
||||
int _maxContentLength;
|
||||
public:
|
||||
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {}
|
||||
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
||||
void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; }
|
||||
void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; }
|
||||
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final{
|
||||
if(!_onRequest)
|
||||
return false;
|
||||
|
||||
if(!(_method & request->method()))
|
||||
return false;
|
||||
|
||||
if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/")))
|
||||
return false;
|
||||
|
||||
if (!request->contentType().equalsIgnoreCase(JSON_MIMETYPE))
|
||||
return false;
|
||||
|
||||
request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
||||
if(_onRequest) {
|
||||
if (request->_tempObject != NULL) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject));
|
||||
if (json.success()) {
|
||||
_onRequest(request, json);
|
||||
return;
|
||||
}
|
||||
}
|
||||
request->send(_contentLength > _maxContentLength ? 413 : 400);
|
||||
} else {
|
||||
request->send(500);
|
||||
}
|
||||
}
|
||||
virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final {
|
||||
}
|
||||
virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final {
|
||||
if (_onRequest) {
|
||||
_contentLength = total;
|
||||
if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) {
|
||||
request->_tempObject = malloc(total);
|
||||
}
|
||||
if (request->_tempObject != NULL) {
|
||||
memcpy((uint8_t*)(request->_tempObject) + index, data, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;}
|
||||
};
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue