Beispiel 4: Web-Server mit konsistenten Web-Site-Daten

Dieses Beispiel ergänzt das Beispiel 3. Das Problem mit inkonsistenten Angaben auf einer Web-Site bei der Nutzung des Template-Processings wird abgestellt. Dazu muss man die Daten zu einem Zeitpunkt sammeln, an dem eine stimmige Zusammenstellung möglich ist, speichern und das Template-Processing aus diesem Speicher bedienen. Hier dient die Klasse UrsAsyncFileProcessorResponse.

Als weiteres Feature wird der SPIFFS-Editor zugangsgeschützt.

Web-Site-Klasse mit Template-Prozessor-Klasse

Zur Zwischenspeicherung der Platzhalterdaten wird eine Klasse von UrsAsyncFileProcessorResponse abgeleitet. Die enthält Variablen zur Aufnahme der Daten und einen dazu passenden Template-Prozessor. Zum Versenden des Responses muss der Request-Handler entsprechend angepasst werden.

Definition der Web-Site-Klasse

Der Standard-Request-Handler der UrsAsyncWebSite-Klasse ist nun nicht mehr ausreichend. Deshalb muss der Request-Handler überschrieben werden.

SysTimeWebSiteEx.h
class SysTimeWebSiteExClass : public UrsAsyncWebSite {
 protected:
   // Handler-Methode, liefert den HTML-Response.
   virtual void handleRequest(AsyncWebServerRequest * request) override;

   // Liefert die URL für diese Seite. Gleichzeitig Dateiname der HTML-Datei.
   virtual String getUrl() override { return "systime.html"; }

   // Liefert alternative Ressourcen-Bezichnungen.
   virtual String getRewrites() override { return "systime|systime.htm|time|time.html|time.htm"; }
};

Definition der Response-Klasse

Weiterhin benötigt man eine Ableitung von UrsAsyncFileProcessorResponse, in der die benötigten Daten zwischengespeichert werden können. Da diese Klasse nur im Request-Handler benötigt wird, definiert man sie am Besten in der Code-Datei. Damit ist sie für den Rest des Programms unsichtbar.

SysTimeWebSiteEx.cpp
class TimeResponse : public UrsAsyncFileProcessorResponse {
public:
  String currentMillis;  // Speicher für die aktuelle Zeit

  // Konstuktor
  TimeResponse(const String & path) : UrsAsyncFileProcessorResponse(path, String(), false) {
    currentMillis = String(millis()); // Aktuellen Zeitwert zwischenspeichern
  }

  // Template-Prozessor
  virtual String templateProcessor(const String & var) override {
    if (var == "millis") return currentMillis;
    return String();
  }
};

Die Klasse erhält zunächst eine Variable zur Aufnahme der Platzhalter-Daten (currentMillis). Im Konstruktor werden die Werte für diese Daten ermittelt und abgelegt. Der Konstruktor benötigt zusätzlich die Angabe, welche Datei zurück geleifert werden soll (path). Zuletzt ist eine passende Template-Prozessor-Methode zu definieren (templateProcessor).

Definition des Request-Handlers

Der Request-Handler ist ebenfalls einfach:

SysTimeWebSiteEx.cpp
void SysTimeWebSiteExClass::handleRequest(AsyncWebServerRequest * request) {
  sendFileResponse(request, new TimeResponse(request->url()));
}

Es  wird eine Instanz der neuen Response-Klasse erstellt und per sendFileResponse versandt. Der Dateiname wird der übergebenen URL entnommen.

Wie bereits oben beschrieben, braucht man sich um das erstellte Objekt nicht weiter zu kümmern. Es wird von der AsyncWebServer-Klasse gelöscht.

Ergebnis

Die neue Konstruktion stellt sicher, das die beiden Zeitangaben auf der Seite identische Werte aufweisen:

Platzhalter-Text

Zugangsschutz

Der Zugangsschutz benötigt drei Angaben: Name des geschützten Bereichs, Benutzerkennung und Passwort. Die Methode begin der Web-Server-Klasse wird so überschrieben, dass ihr diese drei Parameter übergeben werden können:

class MyWebServerClass : public UrsAsyncWebServer {
public:
 // Startet den Web.Server
void begin(String userName, String password, String realmName); 
// ...
};

Mit diesen Daten wird eine Instanz der UrsAsyncRealm-Klasse (protectedArea) bestückt:

UrsAsyncRealm protectedArea;

void MyWebServerClass::begin(String& userName, String& password, String& realmName) {
  protectedArea.name = realmName;
  protectedArea.username = userName;
  protectedArea.password = password;
  // ...

Diese wird dann per setRealm an die Web-Site-Instanz weiter gegeben:

  spiffsEditorWebSite.setRealm(protectedArea);

Download

Das Beispiel ist als "UrsAsyncWebServerExample4" in der Bibliotheks-ZIP-Datei enthalten.