In der heutigen webgesteuerten Welt verarbeiten die Server eine überwältigende Anzahl von Anfragen. Das effiziente Analysieren, Zählen, Interpretieren und Umleiten dieser Anfragen ist von entscheidender Bedeutung, insbesondere bei der Anwendung von MVC Prinzipien.
Mit der Einführung von HTTP Request Handlern auf dem 4D HTTP Server können Sie spezifische Geschäftslogik basierend auf den empfangenen Anfragen auslösen. Diese leistungsstarke Funktion eröffnet viele Möglichkeiten, die in diesem Blogbeitrag näher erläutert werden.
Mit HTTP Request Handlers können Sie so viele Handler wie nötig definieren, die auf bestimmte URL-Muster und HTTP-Verben zugeschnitten sind. Dieser Ansatz bietet eine weitaus größere Granularität als die traditionellen Datenbankmethoden On Web Authentication und On Web Connection und erspart Ihnen die Implementierung umfangreicher Case of Anweisungen.
Request-Handler – warum?
Die Handhabung von Request-Handlern führt zu verschiedenen Szenarien wie z.B.:
- Verwendung einer bestimmten URL als Ressourcenanbieter(z. B. Herunterladen verschiedener Dateien durch Aufruf einer bestimmten URL)
- Verwendung einer bestimmten URL als Datei-Upload-Box(z. B. Hochladen verschiedener Dateien durch Aufruf einer bestimmten URL)
- Weiterleitung auf bestimmte Seiten je nach Geschäftskontext(z. B. Benutzer authentifiziert oder nicht, Seite nicht gefunden, Berechtigungen gewährt oder nicht … usw.)
- Statistiken und Informationen zu einer empfangenen Anfrage aufbewahren
- eine Authentifizierung über oAuth 2.0 abwickeln
wie man einen HTTP-Request-Handler einrichtet
Die HTTP-Request-Handler müssen in der Datei HTTPHandlers.json im Ordner Project/Sources eingerichtet werden.
Diese Datei enthält eine Sammlung von Objekten im JSON-Format. Jedes Objekt verweist auf einen Request-Handler mit den folgenden Informationen:
- das zu behandelnde URL-Muster
- das von der URL verwendete Verb
- die [Singleton-Klasse + Funktion], in der der Request-Handler-Code implementiert ist
Beispiel
HTTPHandlers.json-Datei:
[
{
"class": "GeneralHandling",
"method": "gettingStarted",
"pattern": "start",
"verbs": "get, post"
}
]
Frage: Was bedeutet das?
Antwort: Das bedeutet, dass bei jeder Anfrage, die mit /start/ beginnt und ein GET- oder POST-Verb enthält, die Funktion gettingStarted des Singletons GeneralHandling ausgeführt wird.
wie man den Request-Handler-Code implementiert
Die oben erwähnte Singleton-Klasse muss gemeinsam genutzt werden.
Input: eine Instanz der neuen Klasse 4D.IncomingMessage
Die Anfrage wird auf dem Server als eine Objektinstanz der neuen Klasse 4D.IncomingMessage empfangen.
Die folgenden Informationen sind verfügbar:
- die vollständige Url der Anfrage
- die Teile der Url
- das Verb der Anfrage
- die Kopfzeilen der Anfrage
- die in die URL eingefügten Parameter (falls vorhanden)
- den Textkörper der Anfrage (falls vorhanden)
Anschließend kann der Request Handler all diese Informationen verwenden, um die entsprechende Geschäftslogik auszulösen.
Ausgabe: eine Instanz der Klasse 4D.OutgoingMessage
Bei Bedarf kann der Request Handler ein Objekt der Klasse 4D.OutgoingMessage-Klasse zurückgeben, d.h. einen vollständigen Web-Inhalt, der von einem Browser verarbeitet werden kann (z.B. den Inhalt einer Datei).
Ein einfaches Beispiel für den Anfang
Mit der gleichen HTTPHandlers.json-Datei wie oben:
[
{
"class": "GeneralHandling",
"method": "gettingStarted",
"pattern": "start",
"verbs": "get, post"
}
]
Die Anfrage http://127.0.0.1/start/example?param=demo&name=4D wird mit einem GET-Verb in einem Browser ausgeführt. Sie wird von der Funktion gettingStarted() der folgenden Singleton-Klasse GeneralHandling bearbeitet:
return $resultshared singleton Class constructor()
Function gettingStarted($request : 4D.IncomingMessage) : 4D.OutgoingMessage
var $result:=4D.OutgoingMessage.new()
var $body : Text
$body:="Called URL: "+$request.url+"\n"
$body+="The parameters are received as an object:"+"\n"+JSON Stringify($request.urlQuery; *)+"\n"
$body+="The verb is: "+$request.verb+"\n"
$body+="There are "+String($request.urlPath.length)+" url parts - Url parts are: "+$request.urlPath.join(" - ")+"\n"+"\n"
$result.setBody($body)
$result.setHeader("Content-Type"; "text/plain")
return $result
Die Anfrage wird auf dem Server als $request (eine Objektinstanz der neuen Klasse 4D.IncomingMessage ) empfangen.
Dieses $request-Objekt enthält die folgenden Eigenschaften:
- url (String) – URL der Anfrage
- urlQuery (Object) – Parameter der Anfrage.
- verb (String) – Verb
- urlPath (Sammlung von Strings) – URL-Teile der Anfrage
Hier ist die Antwort:
wie man einen Body in der Anfrage behandelt
Die neue Klasse 4D.IncomingMessage bietet einige Funktionen, um die Kopfzeilen und den Body der Anfrage zu erhalten.
Beispiel
Führen wir ein einfaches Beispiel aus, um eine Datei auf den Server hochzuladen.
Die Datei HTTPHandlers.json:
[
{
"class": "UploadFile",
"method": "uploadFile",
"regexPattern": "/putFile",
"verbs": "POST"
}
]
Beachten Sie, dass das URL-Muster als regulärer Ausdruck mit der Eigenschaft regexPattern angegeben wird.
Die Anfrage http://127.0.0.1:8044/putFile?fileName=testFile wird mit einem POST-Verb und einem Dateiinhalt in ihrem Body ausgeführt.
Die Singleton-Klasse UploadFile:
Function uploadFile($request : 4D.IncomingMessage) : 4D.OutgoingMessage
var $response:=4D.OutgoingMessage.new()
var $body:="Not supported file"
var $fileName; $fileType : Text
var $file : 4D.File
var $picture : Picture
var $created : Boolean
//The file name is given as parameter in the URL
$fileName:=$request.urlQuery.fileName
// The header "Content-Type" provides the format of the body
$fileType:=$request.getHeader("Content-Type")
Case of
// The body contains a pdf file
: ($fileType="application/pdf")
$file:=File("/PACKAGE/Files/"+$fileName+".pdf")
$created:=$file.create()
// The getBlob() function returns the body of the request as a Blob
$file.setContent($request.getBlob())
$body:="Upload OK - File size: "+String($file.size)
// The body contains a jpg image
: ($fileType="image/jpeg")
$file:=File("/PACKAGE/Files/"+$fileName+".jpg")
// The getPicture() function returns the body of the request as a Picture
$picture:=$request.getPicture()
WRITE PICTURE FILE($file.platformPath; $picture)
$body:="Upload OK - Image size: "+String($file.size)
End case
$response.setBody($body)
$response.setHeader("Content-Type"; "TEXT/plain")
return $response
Der Dateiname wird als Parameter(fileName) in der URL angegeben. Er wird im urlQuery Objekt in der Anfrage empfangen.
Funktionen zum Abrufen der Kopfzeilen und des Body der Anfrage
Im obigen Beispiel ist die Funktion getHeader() zu beachten, die eine bestimmte Kopfzeile der Anfrage zurückgibt. Die Klasse 4D.IncomingMessage bietet auch eine Eigenschaft headers (Object), die alle Kopfzeilen der Anfrage enthält.
Die Kopfzeile Content-Type gibt das Format des empfangenen Körpers an. In diesem Beispiel werden nur die Formate pdf und jpeg verarbeitet.
Beachten Sie die Funktionen getBlob() und getPicture() für das $request-Objekt. Sie liefern den Body-Inhalt im entsprechenden Format, das dem Content-Type-Header entspricht.
In der Dokumentation finden Sie weitere Einzelheiten zu diesen Funktionen.
Eine getText() Funktion ist ebenfalls verfügbar und liefert den Body der Anfrage als String (wenn er als String gesendet wurde)
Wenn der Body als gültige JSON-Darstellung übergeben wurde, liefert die Funktion getJSON() seine Auflösung mit dem richtigen Typ (z. B. Object, Collection, String, …).
Umleitung behandeln
Der Request-Handler ist auch in der Lage, auf eine bestimmte Seite umzuleiten, indem er eine Instanz der Klasse4D.OutgoingMessage zurückgibt. Der Location-Header muss verwendet werden, um die Seite anzugeben, auf die umgeleitet werden soll.
Der Wert des HTTP-Status 3xx zeigt an, dass der Client weitere Maßnahmen ergreifen muss, um die Anfrage abzuschließen.
Lassen wir dieses Szenario laufen:
– Der Benutzer kann alle HTML-Seiten im Ordner WebFolder/pages anzeigen, sobald er authentifiziert ist. Solange der Benutzer nicht authentifiziert ist, wird er auf eine Authentifizierungsseite umgeleitet.
– Befindet sich die angeforderte Seite nicht in diesem Ordner, wird eine Seite „Nicht gefunden“ angezeigt.
– Wenn der Benutzer nach einer Seite in einem Unterordner des Ordners /pages fragt, wird eine Seite mit der Aufschrift Not authorized angezeigt.
Die Datei HTTPHandlers.json:
[
{
"class": "PagesHandling",
"method": "handle",
"regexPattern": "/pages/"
}
]
Die Singleton-Klasse PagesHandling:
shared singleton Class constructor()
Function handle($request : 4D.IncomingMessage) : 4D.OutgoingMessage
var $result:=4D.OutgoingMessage.new()
var $file : 4D.File
//The user is not authenticated
If (Session.isGuest())
$result.setHeader("Location"; "/authentication/Authentication.html")
$result.setStatus(307)
Else
//The URL is an html page in the /pages folder
If (($request.urlPath.length=2) && (Position(".html"; $request.url)#0))
$file:=File("/PACKAGE/WebFolder"+$request.url)
//The pages exists
If ($file.exists)
$result.setBody($file.getContent())
$result.setHeader("Content-Type"; "text/html")
$result.setStatus(200)
//The pages does not exist
Else
$result.setHeader("Location"; "/error/NotFound.html")
$result.setStatus(307)
End if
//The URL is NOT a an html page in the /pages folder
Else
$result.setHeader("Location"; "/error/NotAuthorized.html")
$result.setStatus(307)
End if
End if
return $result
Beachten Sie, dass der Request-Handler Zugriff auf das Objekt Session hat, das eine komplexere Geschäftslogik ermöglicht (Überprüfung des Vorhandenseins bestimmter Berechtigungen, Verwendung des gemeinsamen Objekts Session.storage ).
Laden Sie den HDI herunter, um den Umgang mit HTTP-Anfragen zu üben, und warten Sie nicht länger, um in die Welt des Projektmodus einzutreten, der Klassen und andere leistungsstarke Funktionen vorschlägt.