UI-Programm und Gateway-Service

EGL bietet eine Technologie, die einem Service mit Zustandsüberwachung (STATEFUL) entspricht und eine Logik darstellt, die Werte von einem Aufruf zum nächsten beibehält. Die Technologie besteht aus zwei Hauptkomponenten, die auf einem mit Java™ EE kompatiblen Anwendungsserver ausgeführt werden. In der Regel werden beide Komponenten im selben Webprojekt implementiert.
Die beiden Komponenten sind ein UI-Programm und ein UI-Gateway-Service.
Der Anforderer startet das UI-Programm und empfängt Daten, wenn das UI-Programm eine der beiden folgenden Anweisungen aufruft:
Ferner kann das UI-Programm die Steuerung durch Aufruf der folgenden Anweisungen übertragen:

Ein vollständiges Beispiel für ein UI-Programm finden Sie in 'End-to-end-Verarbeitung mit UI-Programm und Datengrid'.

Gateway-Datensatz

Wie im nächsten Abschnitt beschrieben übergibt und empfängt der Anforderer Geschäftsdaten im JSON-Format. Die JSON-Zeichenfolge wird in ein Feld eines Datensatzes vom Typ 'UIGatewayRecord' eingebettet. Im Allgemeinen werden Datensätze dieses Typs beim Codieren eines Anforderers und nicht beim Codieren eines UI-Programms verarbeitet.

Der Typ 'UIGateRecord' ist ein Datensatzabschnitt des Systems, der wie folgt strukturiert ist:
Record UIGatewayRecord
   uiProgramName STRING;
   data STRING;
   dataEncoding EncodingKind;
   terminated Boolean;
end
Bedeutung der einzelnen Felder:
uiProgramName
Eine Zeichenfolge, die den vollständig qualifizierten Namen des UI-Programms angibt, das aufgerufen werden soll. Wenn der Name eines im Paket myPkg enthaltenen UI-Programms beispielsweise Translate und der Gateway-Datensatz gateRec lautet, gilt die folgende Zuordnung:
gateRec.uiProgramName = "myPkg.Translate";

Bei der Antwort des Service auf den Anforderer wird sichergestellt, dass der Feldwert den nächsten aufzurufenden EGL-Abschnitt darstellt (sofern vorhanden). Auch hier wird der Gateway-Datensatz normalerweise nicht explizit im UI-Programm aktualisiert.

data
Eine Zeichenfolge mit den Geschäftsdaten im JSON-Format. Mithilfe der ServiceLib-Konvertierungsfunktionen kann der Anforderer die JSON-Zeichenfolge nach Bedarf speichern oder abrufen.
Die in oder aus JSON konvertierten Geschäftsdaten bestehen in der Regel aus einem Container, der die relevanten Inhalte enthält. Der folgende Datensatzabschnitt enthält beispielsweise eine ganze Zahl:
Record InitialContainer
  initialValue INT;
end
Der folgende Datensatzabschnitt enthält zwei Integer und eine Feldgruppe mit SQL-Datensätzen:
Record RepeatedContainer  
  numberOfRecords INT;
  pageNumber INT = 1;
  sendList theSQLRecord[]{};
end
dataEncoding
Ein Wert, der das Format der Geschäftsdaten angibt, die zwischen dem Anforderer und dem UI-Programm ausgetauscht werden. Dieser Wert veranlasst automatische Datenkonvertierungen. Daten werden in das JSON-Format übertragen und für das Feld dataEncoding ist 'EncodingKind.JSON' der einzig gültige Wert.
terminated
Ein boolescher Wert, der angibt, ob das Programm beendet wird. Für das Feld terminated darf kein Wert zugeordnet werden. Das Feld wird vom UI-Programm automatisch eingestellt. Der Anforderer kann das Feld lesen, um nachfolgende Verarbeitungsaktivitäten zu steuern.

Verhalten des Anforderers

Der Anforderer funktioniert wie folgt:
  1. Deklaration einer Servicezugriffsvariablen des Typs 'UIGatewayService':
    gatewayServiceVar UIGatewayService{@BindService{bindingKey="UIGatewayService"}};
    Das UIGatewayService-Binding im EGL-Implementierungsdeskriptor verfügt über einen Basis-URL-Eintrag wie diesem:
    http://localhost:8080/MyWebProject/restservices/uiGatewayService
  2. Deklaration eines UI-Gateway-Datensatzes vom Typ 'UIGatewayRecord':
    gateRec UIGatewayRecord;
  3. Verwendung der Funktion ServiceLib.convertToJSON zum Konvertieren von Geschäftsdaten in eine JSON-Zeichenfolge, die in das Feld data des UI-Gateway-Datensatzes eingefügt wird. Wenn beispielsweise sendToProgram ein EGL-Datensatz ist, der an das UI-Programm gesendet wird, muss die folgende Anweisung codiert werden:
    gatewayRec.data = ServiceLib.convertToJSON( sendToProgram );

    Die Zeichenfolge gibt den Inhalt wieder, der für das UI-Programm gedacht ist.

  4. Einschluss einer Servicezugriffsanweisung, die den UI-Gateway-Datensatz übergibt. Der Aufruf ist asynchron, wenn er innerhalb von Rich UI erfolgt, und synchron, wenn der außerhalb von Rich UI erfolgt. Beispiel für eine Servicezugriffsanweisung für Rich UI:
    call gatewayServiceVar.invokeProgram(gateRec) 
       returning to callbackFunc onException handleException;
    Die Signatur der Funktion invokeProgram des UI-Gateway-Service lautet wie folgt:
    function invokeProgram(gatewayRecord UIGatewayRecord INOUT);
  5. Verwendung eines Datensatzes vom Typ 'UIGatewayRecord' für den Empfang der vom UI-Gateway-Service zurückgegebenen Daten. Im Folgenden ist die Signatur einer Callback-Funktion im Rich-UI-Handler aufgeführt:
    function callbackFunc(gatewayRecord UIGatewayRecord in)

    Für den Anforderer, der auf eine Anweisung converse des UI-Programms antwortet, muss die Struktur des data-Feldinhalts im empfangenen Gateway-Datensatz der Struktur des data-Feldinhalts entsprechen, der an das UI-Programm zurückgesendet wird. Nur der Inhalt der Daten kann variieren.

    Die an das UI-Programm gesendeten Daten enthalten den vollständig qualifizierten Namen des aufzurufenden EGL-Abschnitts, also den Paket- und den Abschnittsnamen. Wenn der Abschnitt über einen Aliasnamen verfügt, wird der Aliasname anstelle des Abschnittsnamens verwendet. Der Abschnitt kann ein anderes UI-Programm oder eine EGL-Bibliothek sein.

  6. Verwendung der Funktion ServiceLib.convertFromJSON zum Konvertieren der vom UI-Programm empfangenen Daten und Einfügen der konvertierten Daten in eine EGL-Variable. Beispiel: Wenn dataRecord ein EGL-Datensatz ist, dessen Struktur mit der Struktur der erwarteten Daten des UI-Programms übereinstimmt, könnte die Callback-Funktion von RICH UI die folgende Anweisung enthalten:
    ServiceLib.convertFromJSON( gatewayRecord.data, dataRecord);
  7. Wenn der UI-Gateway-Service ein EGL-REST-RPC-Service mit Zustandsüberwachung (STATEFUL) ist, kann der Anforderer ServiceLib.endStatefulServiceSession zum Beenden des Programms aufrufen. Wenn der Anforderer eine Rich-UI-Anwendung ist, muss der Benutzer in diesem Fall die Anwendung im Browser erneut herunterladen, bevor die Anwendung das UI-Programm neu starten kann.
    Beachten Sie, dass die Beendigung der Sitzung zu einer Fehlernachricht führen kann, die auf dem Anwendungsserver mit dem UI-Programm angezeigt wird: Beispiel:
    EGL2156E Die Sitzung, die dem Programm 'MyUIProgram' zugeordnet ist, wurde inaktiviert.

Der Anforderer verwendet JSON-Konvertierungsfunktionen, das UI-Programm üblicherweise aber nicht.

Verhalten des UI-Programms

Das UI-Programm funktioniert wie folgt:
  • Daten können auf zweierlei Weise empfangen werden:
    • Wenn der Aufruf direkt über den Anforderer erfolgt, werden die Daten des Anforderers in den Datensatz eingefügt, der in der Eigenschaft inputUIRecord angegeben ist. Der Datensatz muss ein Basisdatensatz sein, der nicht strukturiert ist. Der Datensatz ist kein Gateway-Datensatz.

      Am Empfang der Daten im Datensatz ist keine JSON-Konvertierungsfunktion beteiligt. Die Konvertierung wird für Sie ausgeführt.

    • Wenn der Aufruf eine Übertragung aus einem anderen Programm ist, werden die Daten aus dem übertragenden Programm in den Datensatz eingefügt, der in der Eigenschaft inputRecord angegeben ist. Der Datensatz muss ein Basisdatensatz sein, der entweder strukturiert oder nicht strukturiert ist. Der Datensatz ist kein Gateway-Datensatz.
  • Daten können wie folgt an den Anforderer zurückgegeben werden:
    • Durch Aufruf einer Anweisung show. Es ist erforderlich, dass das E/A-Objekt in der Anweisung show nicht strukturiert ist. Ferner kann es sich um einen Basis- oder SQL-Datensatz handeln. Die Anweisung kann in einer Bibliotheksfunktion enthalten sein.

      Die Anweisung show ist in einer Bibliothek nur dann gültig, wenn die Bibliothek über ein UI-Programm aufgerufen wird.

    • Durch direkte Rückgabe der Steuerung. Das heißt, die Beendigung erfolgt ohne Ausführung der Anweisung show und die Steuerung wird nicht an ein anderes Programm übertragen.
    • Durch Aufruf einer Anweisung converse. Dies gilt allerdings nur dann, wenn der UI-Gateway-Service als EGL-REST-RPC-Service implementiert wird. Es ist erforderlich, dass das E/A-Objekt in der Anweisung converse nicht strukturiert ist. Ferner kann es sich um einen Basis- oder SQL-Datensatz handeln. Die Anweisung kann in einer Bibliotheksfunktion enthalten sein. Die Anweisung converse ist in einer Bibliothek jedoch nur dann gültig, wenn die Bibliothek über ein UI-Programm aufgerufen wird.

      Die von einer bestimmten Anweisung converse gesendeten Daten müssen wie die von dieser Anweisung empfangenen Daten strukturiert sein.

    Wenn das UI-Programm die Steuerung an den Anforderer zurückgibt, empfängt der Anforderer den UI-Gateway-Datensatz. Dabei gelten die folgenden Aussagen:
    • Nach dem Aufruf einer Anweisung show oder converse durch das UI-Programm enthält das Feld data des UI-Gateway-Datensatzes die JSON-Entsprechung der Geschäftsdaten.
    • Das Feld programName des UI-Gateway-Datensatzes wird in den folgenden Fällen auf eine leere Zeichenfolge gesetzt:
      • Das UI-Programm wurde durch direkte Rückgabe der Steuerung beendet.
      • Das UI-Programm wurde durch eine Anweisung show ohne verzögerte Übertragung beendet.
    • Das Feld terminated des UI-Gateway-Datensatzes wird in den folgenden Fällen auf den Wert 'true' gesetzt:
      • Das UI-Programm wurde durch direkte Rückgabe der Steuerung beendet.
      • Das UI-Programm wurde von einer Anweisung show beendet.

    Die Anweisungen show und converse verwenden keine JSON-Konvertierungsfunktion. Die erforderlichen Konvertierungen werden für Sie ausgeführt. Dazu gehört auch die Konvertierung, die nach der Anweisung converse erfolgt, wenn der Anforderer das Programm erneut aufruft und es zur Verarbeitung der Anweisung veranlasst, die auf die Anweisung converse folgt.

Die Eigenschaften des UI-Programms lauten wie folgt:
alias
Eine optionale Zeichenfolge, die das Programm angibt. Bei Angabe dieser Zeichenfolge muss der Anforderer diesen Wert anstelle des Programmnamens verwenden.
inputRecord
Ein Datensatz, der Daten von einem übertragenden Programm empfängt (siehe oben).
inputUIRecord
Ein Datensatz, der Daten vom UI-Gateway-Service empfängt (siehe oben).
segmented
Ein boolescher Wert, der angibt, ob das UI-Programm im Segmentmodus ausgeführt wird:
true (Standardwert)
Das Programm wird nach den converse-Anweisungen beendet und nach der Benutzerantwort an der entsprechenden Stelle neu geladen.

Die Übernahme des Standardwerts hat den Vorteil, dass während der Bedenkzeit des Benutzers Anwendungsserverressourcen freigegeben werden. Der Effekt der Programmbeendigung erfordert jedoch möglicherweise eine zusätzliche Codierung, da der EGL-Laufzeitcode Dateien und Datenbankverbindungen schließt, Bibliotheken freigibt und die Werte der EGL-Systemvariablen zurücksetzt, die nicht innerhalb einer converse-Anweisung gespeichert werden.

false
Das Programm verbleibt im Speicher, während auf eine Antwort vom Anforderer gewartet wird.

Weitere Informationen finden Sie in 'Segmentierung in Text-UI-Programmen und UI-Programmen'.

Stellen Sie bei der Generierung des UI-Programms sicher, dass die Builddeskriptoroption j2ee auf 'yes' gesetzt ist.

Beachten Sie beim Debug des UI-Programms die folgenden Hinweise:
  • Die Quelle des UI-Gateway-Service ist nicht verfügbar und das Debug für den Service ist nicht möglich.
  • Das Debug für ein UI-Programm ist nur dann möglich, wenn das Programm bereits auf einem Server ausgeführt wird.

Ausnahmebedingungen

Ausnahmebedingungen, die eine Beendigung des UI-Gateway-Service oder UI-Programms zur Folge haben, werden als 'ServiceInvocationException' an die Rich-UI-Anwendung zurückgegeben. Die Ausnahmebedingung kann zur Aktualisierung der zugehörigen Nachricht erneut ausgelöst werden, aber an den Anforderer werden nur die von 'ServiceInvocationException' bereitgestellten Details zurückgegeben. Der in Fettdruck dargestellte Eintrag im folgenden Code hat beispielsweise nur zur Folge, dass die Nachricht geändert wird, die vom UI-Programm auf dem Anwendungsserver angezeigt wird:
Record MyException type Exception end

Program MyUIProgram type UIProgram {}
   function main()
      try
         // get an array of data from a relational database
         get mySQLRecord; 
            onException(except AnyException)
               throw new MyException{message = 
                         "Error at get mySQLRecord:  " + except.message};               
      end
   end
end

Kommt es während eines laufenden Datenaustauschs mit einem Anforderer zu einer Überschreitung des Zeitlimits für das UI-Programm, wird die Ausnahmebedingung beim nächsten Aufruf des Programms durch den Anforderer zurückgegeben.


Feedback