PASOE verze 11.6.3 přichází s novou komunikační vrstvou, která umožňuje vývojářům webových aplikací lépe pracovat s daty poskytovanými business entitami na progressovském aplikačním serveru. Rozhraní se jmenuje " Web Handlers " a poskytuje metody, jak prezentovat data poskytovaná business entitami v různých formátech. V našem článku si ukážeme, jak lze jednoduše generovat odpovědi ve formátu JSON.

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.

createOEproject.png

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.

dbConnected.png

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

BE.png

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.

customerBE.png

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 http: //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):

JSONscreen.png

RawDataScreen.png

HeadersScreen.png

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.


Nahoru