Logo Oracle Deutschland   Application Express Community

APEX URL-Syntax - revisited

Stand APEX-Version Datenbankversion
Mai 2016 alle alle

Mit der URL-Syntax arbeitet man als APEX-Entwickler eigentlich täglich, ständig setzt man f?p= URLs zusammen. Der grundsätzliche Aufbau einer APEX-URL ist hinreichend bekannt:

f?p=Application-ID:
    Page-ID: 
    Session-ID:
    Request:
    Debug:
    ClearCache:
    Item-Names:
    Item-Values:
    PrinterFriendly

URLs zusammensetzen

In den ersten APEX-Versionen wurden die meisten URLs einfach nur zusammengesetzt und verwendet. Heute reicht das in den meisten Fällen nicht mehr aus.

  • Die immer öfter aktive Session State Protection erfordert in vielen Fällen (Übergabe von Werten für geschützte APEX-Elemente), dass die URL mit einer Prüfsumme versehen ist.
  • Ist die Zielseite der URL ein modaler Dialog, so muss die URL in einen Javascript-Aufruf eingebettet werden, der den modalen Dialog öffnet und die Seite darin lädt.

Inzwischen sollte also jede generierte URL mit der Funktion APEX_UTIL.PREPARE_URL "vorbereitet" werden. Ist eine Checksumme erforderlich (das richtet sich nach den Einstellungen der Zielseite und der im URL verwendeten Elemente), so wird diese berechnet und hinzugefügt. Ist die Seite ein modaler Dialog, so wird der entsprechende Javascript-Aufruf generiert. Wenn man PREPARE_URL immer verwendet, funktionieren die generierten Links auch dann noch, wenn die Zielseite später in einen modalen Dialog verwandelt oder die Session State Protection nachträglich aktiviert wird.

Konsequenzen hat das, wenn man eine APEX-URL in Javascript-Funktionen verwenden möchte. PREPARE_URL steht nur auf dem Server - in PL/SQL - zur Verfügung. Soll eine generierte URL also in einer Javascript-Funktion verwendet werden, so sollte man diese vorab beim Page Load generieren, in einem versteckten Element (Hidden-Item) speichern und dann in Javascript mit $v("P1_HIDDEN") verwenden.

URL Komponenten

Eine APEX-URL ist zweistufig aufgebaut. Das "f", mit dem jede URL beginnt, referenziert die PL/SQL-Prozedur "f", welche der zentrale Einstiegspunkt für das APEX-Page Rendering ist. Jeder Parameter dieser Prozedur kann durch einen URL-Parameter gesetzt werden. Der wichtigste Parameter ist "p", der festlegt, welche Seite, welcher Applikation, in welcher Session und mit welchen Parametern betroffen ist. Innerhalb von "p" werden die einzelnen Parameter durch Doppelpunkte getrennt. Im folgenden geht es zuerst um die Bestandteile des Parameters "p", danach werden die anderen Parameter der Prozedur "f" kurz erläutert.

Erstellt man eine URL, so verwendet man oft Variablen für die aktuelle Anwendungs-ID, die Session oder andere. Hier bieten sich Bind-Variablen oder die Substitution-Syntax an. Was man am verwenden sollte, hängt vom Kontext ab: In einer Region vom Typ Static Content oder im HTML-Code eines Templates muss man Substitution Strings verwenden; Bind-Variablen oder die PL/SQL-Funktion v() funktionieren nicht, man befindet sich ja auch nicht in einem SQL oder PL/SQL-Kontext. Möchte man also eine URL generieren, damit auf die Seite 1 der aktuellen Anwendung verzweigen und das Item P1_ID setzen, so geht man wie folgt vor:

f?p=&APP_ID.:&APP_PAGE_ID.:&APP_SESSION.::::P1_ID:1

In einer SQL-Abfrage (Report, Kalender oder Diagramm) kann man zwar auch mit Substitutions arbeiten, davon ist aber abzuraten. Grund ist, dass ein Substitution String vor dem SQL-Parsing durch den Datenbankkern ersetzt wird - eine Bind-Varaiable aber erst danach. Mit einem Substitution String wird also für jede APEX-Session (wegen der unterschiedlichen Session-IDs) ein völlig neues SQL generiert, welches dann komplett neu verarbeitet werden muss (Hard Parse).

Besser ist es mit Bind-Variablen - diese sind wie Parameter eines SQL-Kommandos zu sehen: Bei fortfolgenden Ausführungen werden die Ressourcen der ersten Ausführung vom Datenbankkern wiederverwendet. Möchte man, zum Beispiel in einer Berichtsabfrage, eine URL mit SQL-Funktionen generieren, so geht man am besten wie folgt vor:

select
  'f?p=' || :APP_ID || ':' || :APP_PAGE_ID || ':APP_SESSION' || '::::P1_ID:' || emp.empno as link_url
from emp

Etwas übersichtlicher wird es, wenn man die ab APEX 5.0 verfügbare Funktion APEX_PAGE.GET_URL verwendet. Diese nimmt Parameter entgegen und generiert die URL entsprechend. Man muss die Strings nicht mehr selbst mit || konkatenieren und der Code wird übersichtlicher. Der für die Session State Protection nötige Aufruf von APEX_UTIL.PREPARE_URL ist in dieser Funktion ebenfalls bereits enthalten; das Ergebnis von GET_URL ist im Bedarfsfalle also mit der nötigen Checksum ausgestattet und kann sofort verwendet werden.

select
  apex_page.get_url(
    p_application => :APP_ID,
    p_page        => :APP_PAGE_ID,
    p_session     => :APP_SESSION,
    p_items       => 'P1_ID',
    p_values      => emp.empno
  ) as link_url
from emp;

LINK_URL
--------------------------------------------------------------------------------
f?p=130:1:16998716660165::NO::P1_ID:7839&cs=1n6eilE5ipl9byXyUPIIYmijtYAUxB9&ellipsis;

URL-Komponenten - 1. Applikations-ID

Die Application-ID ist typischerweise numerisch, wird allerdings in den seltensten Fällen hart kodiert. Man muss einfach immer davon ausgehen, dass die Anwendung, die man gerade entwickelt, exportiert und unter einer anderen ID wieder importiert wird. Daher sollte die Applikations-ID immer dynamisch, mit Hilfe des APEX-Items APP_ID (Substitution &APP_ID.), eingebaut werden. Der APEX Advisor bietet übrigens einen Check an, mit dem man seine Applikation auf etwaige hartkodierte Application-IDs hin prüfen kann.

Neben der numerischen Applikations-ID erlaubt APEX auch das Festlegen eines Anwendungs-Alias - das geschieht in den Gemeinsamen Komponenten bei den Application Definition Attributes. Allerdings eignet sich der Alias nicht dazu, die Anwendungs-ID komplett aus der URL zu verbannen. Dazu müsste die Variable APP_ALIAS in jeder URL anstelle von APP_ID verwendet werden, was in der Praxis fast nirgendwo der Fall sein dürfte. Außerdem ersetzt APEX den Alias, beim ersten Aufruf durch den Endanwender, durch die numerische ID, so dass diese dann doch wieder in der Browser-Adressleiste erscheint.

Theoretisch muss der Anwendungs-Alias nur im Workspace eindeutig sein; in unterschiedlichen Workspaces kann man ein Alias also (theoretisch) mehrfach verwendet werden. Solange man als Entwickler am Workspace eingeloggt ist, funktioniert das alles auch problemlos. Allerdings sind Endanwender in der Regel nicht am Workspace eingeloggt - die Information, in welchem Workspace gesucht werden soll, fehlt APEX also. Ruft der Endanwender eine URL mit Anwendungs-Alias auf, und der Alias existiert in der APEX-Instanz mehrfach, so führt das zu folgendem Fehler.

Der verwendete Anwendungsalias existiert mehrfach in der APEX-Instanz

Der verwendete Anwendungsalias existiert mehrfach in der APEX-Instanz

Gibt man den Workspace mit dem URL-Parameter &c=WORKSPACE_NAME ebenfalls mit, so funktioniert die Namensauflösung wieder: APEX findet die Anwendung und ersetzt den Alias durch die numerische Applikations-ID. Das bedeutet aber, dass man den Workspace-Namen in die URL aufnehmen muss - und auch der kann sich mal ändern.

Aufpassen sollte man mit den Aliasnamen beim Export- und Import der Anwendung. Angenommen, man verwendet einen Alias für eine Anwendung und importiert eine neue Version unter einer neuen ID (weil man die alte Version noch weiter betreiben möchte). Ist der Alias im Workspace bereits vorhanden, so wird er während des Import-Vorgangs durch einen eindeutigen Wert ersetzt. Wenn man nun den Alias von der alten auf die neue Version "umschalten" möchte, muss man in beiden Applikationen eine Änderung vornehmen.

Man sieht deutlich, dass Anwendungs-Aliasnamen ihre Grenzen haben. Beim Verwenden sollte man diese kennen und berücksichtigen.

2. Seiten-ID

Die aktuelle Seite wird mit :APP_PAGE_ID oder &APP_PAGE_ID. angesprochen. Auch für Seiten kann ein Page Alias verwendet werden. Da der Page-Alias nur innerhalb der Applikation selbst eindeutig sein muss, ist er wesentlich leichter handzuhaben als der Anwendungs-Alias.

3. Session-ID

Diese muss natürlich in jede URL korrekt eingebaut werden; ansonsten wird eine neue Session geöffnet und der Endanwender landet auf der Login-Seite. Die aktuelle Session-ID findet sich in :APP_SESSION bzw. &APP_SESSION.. Für öffentliche Anwendungen kann die Session-ID Null "0" verwendet werden. Mehr Informationen dazu finden sich in der Dokumentation: Facilitating Bookmarks by Using Zero as the Session ID.

4. Request

Wird ein Page Submit durchgeführt, so enthält die Umgebungsvariable :REQUEST bzw. &REQUEST. den Namen des Buttons - im Page Processing weiss man also, welcher Button geklickt wurde. Man kann REQUEST aber auch in der URL setzen und so eine Information für etwaige onLoad-Prozesse, Validations oder Computations mitgeben. Möchte man einen AJAX-Callback aufrufen, so wird der Name ebenfalls im REQUEST angegeben. So kann ein AJAX Callback namens GetData in Anwendung 100 auf Seite 1 auch direkt angesprochen (und getestet) werden. Der Community-Tipp "D3js" in APEX-Anwendungen integrieren zeigt dies anhand eines Beispiels.

f?p=100:1:&APP_SESSION.:APPLICATION_PROCESS=getData

5. Debug

Mit dem fünften URL-Parameter kann APEX-Debugging ein- und ausgeschaltet werden. Meistens wird hier nur YES oder NO verwendet. Allerdings kennt das APEX-Debugging insgesamt 9 Ebenen, die sich mit LEVEL1 bis LEVEL9 auch per URL ansprechen lassen. YES aktiviert Level 4 (Info). Level 1 (Error) loggt die wenigsten Informationen, Level 9 (Engine Trace) die meisten.

Die Levels 8 (Engine Enter) und 9 (Engine Trace) loggen extrem viele Details der APEX-Engine selbst und sind für die Anwendungsentwicklung sicherlich nur mäßig interessant; die Levels 5 (App Enter) und 6 (App Trace) können in eigenem PL/SQL Code aber sehr gut genutzt werden, um detaillierteres Logging in der eigenen Anwendung durchzuführen.

6. Clear Cache

Hier werden im einfachsten Fall durch Komma getrennte Seitennummern angegeben, für die der Session State gelöscht werden soll - alle Items dieser Seite werden also auf NULL gesetzt. Anstelle von Seitennummern können auch Namen von Collections verwendet werden; deren Inhalte werden dann gelöscht.

Das Schlüsselwort RP für Reset Pagination haben die meisten Entwickler sicherlich schon gesehen - es setzt etwaige vorgeblätterte Berichte auf der Zielseite wieder auf die erste Seite zurück.

Die Schlüsselworte APP und SESSION räumen richtig auf (und werden daher nur selten genutzt): APP setzt alle Items der Anwendung zurück; SESSION alle Items aller Anwendungen in der aktuellen APEX-Session.

6. Item Names und Item Values

Diesen Teil der URL-Syntax verwendet man am häufigsten - im Grunde genommen ist es einfach: Item Names enthält die kommaseparierte Liste von APEX-Elementen, die man mit dem URL-Aufruf setzen möchte, danach kommt der Doppelpunkt und es folgt die kommaseparierte Liste der Werte, mit denen die Elemente gesetzt werden sollen. So weit, so gut.

Häufig tritt aber die Frage auf, wie man Doppelpunkte oder Kommata als Wert für ein Element übergeben kann - denn dies sind ja spezielle Zeichen in der URL-Syntax. Nun, mit Hilfe des Backslash wird das möglich. Beginnt eine Angabe mit dem Backslash, so gehören alle Zeichen bis zum nächsten Backslash, gefolgt vom Komma, dazu. Der Backslash wirkt wie ein Quote-Character.

Doppelpunkte und Kommata als Elementwerte per URL übergeben

Doppelpunkte und Kommata als Elementwerte per URL übergeben

7. Printer Friendly

Wird hier ein YES übergeben, so wird die "druckfreundliche" Ausgabe von APEX aktiviert: APEX-Elemente werden nur lesbar (und nicht als Formularelemente) angezeigt; außerdem wird anstelle des normalen Seitentemplate das Printer Friendly Template verwendet. In der Praxis stellt die druckfreundliche Ausgabe, die APEX out-of-the-box bietet, meist nicht zufrieden. Der Community Tipp Druckfreundliche APEX-Seiten mit CSS: Der Browser kann mehr als man denkt enthält einige Tipps und weiterführende Ideen zum Thema.

Weitere URL-Parameter

Bis hierher wurden zwar viele APEX-URL-Parameter beschrieben; aus Sicht des Browsers ging es dagegen nur um einen einzigen, den Parameter "p" der PL/SQL-Prozedur "f". Wer wissen möchte, welche Parameter noch möglich sind, kann sich "f" einfach in SQL*Plus anschauen.

SQL> desc f
PROCEDURE f
 Argument Name                  Typ                     In/Out Defaultwert?
 ------------------------------ ----------------------- ------ --------
 P                              VARCHAR2                IN     DEFAULT
 P_SEP                          VARCHAR2                IN     DEFAULT
 P_TRACE                        VARCHAR2                IN     DEFAULT
 C                              VARCHAR2                IN     DEFAULT
 PG_MIN_ROW                     VARCHAR2                IN     DEFAULT
 PG_MAX_ROWS                    VARCHAR2                IN     DEFAULT
 PG_ROWS_FETCHED                VARCHAR2                IN     DEFAULT
 FSP_REGION_ID                  VARCHAR2                IN     DEFAULT
 SUCCESS_MSG                    VARCHAR2                IN     DEFAULT
 NOTIFICATION_MSG               VARCHAR2                IN     DEFAULT
 CS                             VARCHAR2                IN     DEFAULT
 S                              VARCHAR2                IN     DEFAULT
 TZ                             VARCHAR2                IN     DEFAULT
 P_LANG                         VARCHAR2                IN     DEFAULT
 P_TERRITORY                    VARCHAR2                IN     DEFAULT
 P_DIALOG_CS                    VARCHAR2                IN     DEFAULT
 X01                            VARCHAR2                IN     DEFAULT

Die meisten der Parameter sind für APEX selbst gedacht und sollten nicht vom Entwickler gesetzt werden. Einige davon sind aber durchaus interessant.

  • P_TRACE=YES sorgt dafür, dass auf dem SQL-Tracing auf dem Datenbankserver aktiviert und ein Tracefile geschrieben wird. Das kann sehr nützlich beim Performance-Tuning sein. Das Tracefile liegt im Filesystem des Datenbankservers (user_dump_dest); Sie brauchen also ggfs. die Hilfe des Datenbankadministrators, um heranzukommen.
    Für die Experten: APEX aktiviert das SQL Trace wie folgt:
    alter session set events='10046 trace name context forever, level 12'
    
  • P_SEP erlaubt es, das Trennzeichen für den Parameter "p" vom Doppelpunkt auf ein anderes Zeichen umzusetzen. In der Praxis wird das, insbesondere seit der oben beschriebene Backslash für Item Values genutzt werden kann, aber nur noch selten benötigt.
  • P_LANG dient zum Umschalten der Session-Sprache, wenn dies in den Application Definition Attributes im Bereich Globalization entsprechend eingestellt ist (Session).
    Session als Einstellung für die Anwendungssprache einstellen

    Session als Einstellung für die Anwendungssprache einstellen

  • Als X01 können Sie einen beliebigen Wert übergeben, der serverseitig in der PL/SQL Packagevariablen apex_application.g_x01 bereitgestellt wird. X01 wird aber nicht im Session State gespeichert - es steht also nur für das Rendering der Seite oder des AJAX-Callbacks bereit. Wenn Sie also per URL einen Wert übergeben wollen, der nur einmalig und nicht im Session State benötigt wird, so ist X01 hierfür bestens geeignet - denn die Ressourcen zum Speichern des Wertes im Session State werden gespart. Der Community-Tipp Dateien aus Datenbanktabellen mit APEX bereitstellen zeigt, wie X01 genutzt werden kann.
  • C wurde bereits erläutert; damit kann der Workspace-Name übergeben werden, in dem ein etwaiger Application Alias aufgelöst werden soll. Das ist dann interessant, wenn der Application Alias in der APEX-Instanz mehrfach verwendet wird.

Die verbleibenden URL-Parameter sind sehr speziell und für die APEX-Engine selbst vorgesehen. Teilweise kann man damit experimentieren, teilweise sind die Parameter auch geschützt. So legen die Parameter NOTIFICATION_MSG und SUCCESS_MSG zwar nahe, dass man APEX-Benachrichtigungen damit manuell auslösen kann, ein kurzer Test zeigt jedoch, dass APEX diese (teilweise sensiblen) Nachrichten durch eine Prüfsumme schützt.

Übrigens: Selbstverständlich ist die APEX-URL-Syntax dokumentiert. Im Kapitel Understanding URL Syntax des Application Express Application Builders Users' Guide finden Sie alle Details. l

Zurück zur Community-Seite