WebHandler poskytuje efektivnější a jednodušší komunikační vrstvu než REST. Je kompletně napsán v OOABL (jedná se vlastně o novou třídu v OOABL), je jednodušší jej přizpůsobit vašim vlastním potřebám a má zlepšené možnosti ladění. Hlavní výhodou WebHandleru je, že dává programátorům plnou kontrolu nad vstupními a výstupními daty.
WEB vrstva zpracovává požadavky (requests) a odpovědi (responses), které používají standardní řídící příkazy HTTP (verbs). To zahrnuje interakci s klienty, jako jsou WebSpeed a OpenHTTP. Chcete-li změnit výchozí adresu URL, můžete přidat další WebHandlery nebo změnit výchozí mapování WebHandleru. To se provede v konfiguračním souboru openedge.properties pro instanci PASOE, kde se definuje jejich mapování na konkrétní adresy URL, například:
defaultHandler=OpenEdge.Web.CompatibilityHandler webhandler1=MyHandler:/mycustomer webhandler2=MyHandler:/mycustomer/{custid} |
OpenEdge.Web.CompatibilityHandler zajišťuje kompatibilitu s aplikacemi WebSpeed SpeedScript a CGI Wrapper. Je výchozím obslužným programem používaným v instanci ve vývojovém prostředí.
Vytvoření těchto služeb budeme ilustrovat na dvou příkladech z databáze znalostí. Předpokládejme, že máme instanci serveru PASOE s připojenou databází sports2000.
V prvním příkladu vytvoříme nový PAS for OpenEdge projekt, např. webh1. Vybereme typ serveru a WEB jako transportní vrstvu.
Volbou tlačítka Next v následném kroku zkontrolujeme, zda je projekt připojen k instanci aplikačního serveru a dále, zda je připojena databáze sports2000.
Průvodce automaticky vytvoří třídu WebHandler, v našem případě webh1Handler.cls, obsahující tři metody: HandleNotAllowedMethod, HandleNotImplemented a HandleGet. První dvě se obsluhují zpracování chybových stavů a v našem příkladu je ponecháme beze změny. Metoda HandleGet, se kterou budeme pracovat, je hlavní metoda, ve které můžete zpracovávat data přijatá z odpovědi BE (response) a prezentovat je v požadovaném formátu, v našem případě JSON. Příklad nepracuje se vstupními parametry a zobrazí první řádek z tabulky Customer.
V dalším kroku vytvoříme datový objekt. V Průzkumníkovi (Project Explorer) vybereme název projektu (webh1) a klepneme pravým tlačítkem myši na Nový -> Business Entity.
Zadáme název (Resource Name) customerBE, klikneme na tlačítko Next a vybereme tabulku Customer z databáze sports2000. ResourceURI necháme beze změny.
Stisknutím tlačítka Finish vytvoříme třídu customerBE.cls (a také soubor
customerBE.i).
Na tuto třídu se bude odkazovat Webhandler, konkrétně so ubor webh1Handler.cls. Nyní upravíme jeho
metodu HandleGet tak, aby poskytovala odpověď typu JSON na dotaz na entitu
customerBE.
Je vidět, že vývoj a úpravy těchto metod vyžadují znalost objektově orientovaného programování, konkrétně Progress OOABL a vhodných referencí, na druhé straně poskytují vývojářům mnoho nových možností k prezentaci dat a business logiky. V následujícím příkladu odpověď HTTP dotazu načte obsah "temp-table" ttCustomer (z objektu customerBE) a zobrazí jej prostřednictvím objektu JSON. Nejprve si ukážeme modifikaci samotnéhu objektu WebHandler.
USING Progress.Lang.*. USING OpenEdge.Web.WebResponseWriter. USING OpenEdge.Net.HTTP.StatusCodeEnum. USING OpenEdge.Web.WebHandler. USING customerBE.*. USING Progress.Json.ObjectModel.*. BLOCK-LEVEL ON ERROR UNDO, THROW. CLASS webh1Handler INHERITS WebHandler: {"customerbe.i"} /*------------------------------------------------------------------------------ Purpose: Handler for unsupported methods. The request being serviced and an optional status code is returned. A zero or null value means this method will deal with all errors. Notes: ------------------------------------------------------------------------------*/ METHOD OVERRIDE PROTECTED INTEGER HandleNotAllowedMethod( INPUT poRequest AS OpenEdge.Web.IWebRequest ): /* Throwing an error from this method results in a 500/Internal Server Error response. The web handler will attempt to log this exception. See the HandleGet method's comments on choosing a value to return from this method. */ UNDO, THROW NEW Progress.Lang.AppError("METHOD NOT IMPLEMENTED"). END METHOD. /*------------------------------------------------------------------------------ Purpose: Handler for unknown methods. The request being serviced and an optional status code is returned. A zero or null value means this method will deal with all errors. Notes: ------------------------------------------------------------------------------*/ METHOD OVERRIDE PROTECTED INTEGER HandleNotImplemented( INPUT poRequest AS OpenEdge.Web.IWebRequest ): /* Throwing an error from this method results in a 500/Internal Server Error response. The web handler will attempt to log this exception. See the HandleGet method's comments on choosing a value to return from this method. */ UNDO, THROW NEW Progress.Lang.AppError("METHOD NOT IMPLEMENTED"). END METHOD. /*------------------------------------------------------------------------------ Purpose: Default handler for the HTTP GET method. The request being serviced and an optional status code is returned. A zero or null value means this method will deal with all errors. Notes: ------------------------------------------------------------------------------*/ METHOD OVERRIDE PROTECTED INTEGER HandleGet( INPUT poRequest AS OpenEdge.Web.IWebRequest ): DEFINE VARIABLE oResponse AS OpenEdge.Net.HTTP.IHttpResponse NO-UNDO. DEFINE VARIABLE oWriter AS OpenEdge.Web.WebResponseWriter NO-UNDO. DEFINE VARIABLE oBody AS OpenEdge.Core.String NO-UNDO. DEFINE VARIABLE beCustomer AS customerBE NO-UNDO. DEFINE VARIABLE pcFilter AS CHAR NO-UNDO. DEFINE VARIABLE lcJSON AS LONGCHAR NO-UNDO. DEFINE VARIABLE jObj AS JsonObject. DEFINE VARIABLE htt AS HANDLE. jObj = NEW JsonObject(). /* Get data from the BE */ beCustomer = NEW customerBE(). beCustomer:ReadcustomerBE(INPUT pcfilter,OUTPUT DATASET dsCustomer). htt = TEMP-TABLE ttCustomer:HANDLE. htt:WRITE-JSON("JsonObject", jObj). ASSIGN oResponse = NEW OpenEdge.Web.WebResponse() oResponse:StatusCode = INTEGER(StatusCodeEnum:OK) . /* This body object can be a string or something else (JsonObject for instance) */ lcJSON= jObj:GetJsonText(). ASSIGN oBody = NEW OpenEdge.Core.String(lcJSON). ASSIGN oResponse:Entity = oBody /* HTTP messages require a content type */ oResponse:ContentType = 'application/json':u /* ContentLength is good too */ oResponse:ContentLength = oBody:Size . /* The WebResponseWriter ensures that the status line and all headers are writted out before the message body/entity. */ ASSIGN oWriter = NEW WebResponseWriter(oResponse). oWriter:Open(). /* Finish writing the response message */ oWriter:Close(). /* A response of 0 means that this handler will build the entire response; a non-zero value is mapped to a static handler in the webapp's /static/error folder. The mappings are maintained in the webapps's WEB-INF/web.xml A predefined set of HTTP status codes is provided in the OpenEdge.Net.HTTP.StatusCodeEnum enumeration */ RETURN 0. END METHOD. END CLASS. |
Do prohlížeče nyní zadáme URL instance PASOE, například https: //localhost:8810/webh1/web/webh1
(nebo https://localhost:8811/webh1/web/webh1 pro zabezpečené připojení).
Výsledkem bude obrazovka rozdělená do tří záložek (folders):
Druhým příkladem, kde si ukážeme především zpracování vstupních parametrů, se budeme zabývat v dalším článku.
Autoři: Michal Džmuráň volně dle Piotr Tucholski.