URL dieses Artikels:

zu Ausgabe: 2.2003
Der zweite Schnappschuss
Delphi WebSnap: Daten im Web, Teil 2
von Bob Swart
Im Entwickler 01/2003 habe ich Ihnen gezeigt, wie wir eine WebSnap-Applikation mit WebSnap-Datenmodulen und WebSnap-Seitenmodulen unter Verwendung von dbExpress erstellen können, um auf die InterBase-Datenbank employee.gdb zuzugreifen. In dieser Ausgabe möchte ich diese WebSnap-Applikation erweitern und Ihnen zeigen, wie wir Haupt/Detail-Beziehungen (welche Angestellten haben welchen spezifischen Job) aufbauen, wie wir Zugriffsrechte (Authorisation) der Applikation hinzufügen und letztendlich wie wir die Applikation auf einen realen Webserver aufsetzen können.

Haupt/Detail
Lassen Sie uns mit der Haupt/Detail-Beziehung beginnen. Und zwar aus dem Grund, weil ich zeigen muss, dass alle Angestellten mit einem bestimmten Job verbunden sind. Letztes Mal erstellten wir Seiten um sowohl die verfügbaren Jobs als auch die Angestellten zu zeigen und dieses Mal muss ich diese Informationen kombinieren. Aber da ich die normale Angestelltenübersicht nicht entfernen möchte, brauche ich einen anderen DataSet. Dieses Mal werden wir anstatt TSQLTable eine TSQLDataSet-Komponente verwenden. Nennen Sie diese sdsEMPJOB, weisen Sie deren SQLConnection-Eigenschaft der SQLConnection-Komponente zu, verändern Sie die CommandType-Eigenschaft auf ctTable und selektieren Sie EMPLOYEE als Wert für die CommandText-Eigenschaft. Führen Sie einen Doppelklick auf den sdsEMPJOB-SQLDataSet aus, um den Felder-Editor zu starten. Letztes Mal haben wir alle Felder den tblJOB- und tblEMP-Tabellen hinzugefügt, aber dieses Mal brauche ich nicht alle Felder der Angestellten zu sehen (wenn sie angezeigt werden, dann in Konjunktion mit den Jobinformationen). Tatsächlich will ich nur die folgenden fünf Felder sehen: EMP_NO, PHONE_EXT, HIRE_DATE, DEPT_NO, JOB_CODE und FULL_NAME. Stellen Sie also sicher, dass Sie nur diese im Felder-Editor hinzufügen. Bevor Sie den Felder-Editor auswählen, selektieren Sie das EMP_NO-Feld, gehen zum Objektinspektor und setzen die pfInKey-Untereigenschaft der ProviderFlags-Eigenschaft auf True, um sicherzustellen, dass wir diesen Record eindeutig auf Basis von dem EMP_NO-Feld identifizieren können.

Unter die sdsEMPJOB-SQLDataSet-Komponente ziehen Sie eine TDataSetProvider-Komponente, nennen Sie diese dspEMPJOB und verbinden Sie deren DataSet-Eigenschaft mit sdsEMPJOB. Unter die dspEMPJOB-DataSetProvider-Komponente ziehen Sie eine TClientDataSet-Komponente, nennen Sie diese cdsEMPJOB und verbinden deren ProviderName-Eigenschaft mit dspEMPJOB.

Wir müssen noch die Haupt/Detail-Beziehung zwischen cdsEMPJOB und cdsJOB definieren und dazu ziehen wir eine unterstützende TDataSource-Komponente hinzu. Nennen Sie diese dsJOB und lassen deren DataSet-Eigenschaft auf cdsJOB zeigen. Weisen Sie dsJOB der MasterSource-Eigenschaft von cdsEMPJOB zu und klicken Sie auf die Unvollständigkeitsanzeige von der MasterFields-Eigenschaft der cdsEMPJOB-Komponente, um den Feldverbindungs-Designer zu starten (siehe Abbildung 1).


Abb. 1: Der Feldverbindungs-Designer

Unter Verwendung von dem Feldverbindungs-Designer-Dialog können wir definieren, dass das JOB_CODE-Hauptfeld (von cdsJOB) mit dem JOB_CODE-Detailfeld (von cdsEMPJOB) verbunden ist. Dieses beendet die Arbeit mit dem WebSnap-Datenmodul (siehe Abbildung 2.


Abb. 2: Die WebSnap-Datenmodule

Erweiterung der Jobs
Lassen Sie uns nun die Seitenmodule für die Jobs erweitern. Öffnen Sie also die Unit pmJobs.pas und führen Sie einen Doppelklick auf den AdapterPageProducer aus, um den Editor für Web-Seiten erneut zu starten. Ich möchte einen Button dem Gitter hinzufügen, der uns zu einer neuen Seiten führen soll, die sowohl Detailinformation über die Jobs als auch eine Liste der Angestellten mit diesem Job zeigen soll (die Daten von der Haupt/Detail-Beziehung, die wir gerade definiert haben).

Im Editor für Web-Seiten selektieren Sie die AdapterGrid-Komponente, führen darauf einen Rechtsklick aus und selektieren Neue Komponente. In dem folgenden Dialog selektieren Sie eine AdapterCommandColumn. Dies wird eine neue Spalte in dem Gitter hinzufügen, die Schaltflächen für alle möglichen Aktionen anzeigt, die in dem DataSetAdapter definiert sind (welche ziemlich viele sind). Um die überflüssigen Schaltflächen zu entfernen, führen Sie einen Rechtsklick auf der AdapterCommandColumn aus, wählen Befehle hinzufügen und selektieren Sie nur das BrowseRow-Kommando. Dies wird sicherstellen, dass nur eine Schaltfläche im AdapterGrid angezeigt wird.

Da wir immer noch im Browse-Modus sind, macht die Schaltfläche hier erst einmal nichts, kann aber verwendet werden, um zu anderen Seitenmodulen zu springen. Wir können dies in der PageName-Eigenschaft angeben, welche in der Grundeinstellung leer ist. Wenn wir den Name Job dort eingeben und dann einen Klick auf die Schaltfläche ausführen (wenn diese im Browser angezeigt wird), wird das in einem Sprung zu dem Seitenmodul mit Namen Job resultieren. Beachten Sie, dass wir bisher kein Seitenmodul mit Namen Job haben, aber das werden wir in einer Minute nachholen.

Unabhängig von dem Seitennamen können wir also die Beschriftung der Schaltfläche verändern, um anzuzeigen, dass wir zu einem anderen Seitenmodul mit mehr Details über den Job als auch die Angestellten in diesem speziellen Job verzweigen. Setzen Sie die Beschriftung beispielsweise auf Details, was in der folgenden Designzeitansicht von dem Job-Seitenmodul resultiert.

Wenn Sie mögen, können Sie die Beschriftung von dem Gitter verändern, indem Sie die anderen AdapterGrid-Spalten selektieren und deren Caption-Eigenschaft ebenso ändern (indem Sie das vorangestellte JOB_ bei allen Feldern außer dem ersten löschen).

Job und Angestellte
Lassen Sie uns nun das neue Seitenmodul mit Namen Job erstellen, dass genauere Informationen aus der Job-Tabelle als auch über die Angestellten (in einer Haupt/Detail-Beziehung), die diesen Job haben, anzeigen wird. Wählen Sie Datei | Neu - Weitere, gehen Sie zu dem WebSnap-Register und führen Sie einen Doppelklick auf das WebSnap-Seitenmodul-Icon aus. In dem folgenden Dialog selektieren Sie einen AdapterPageProducer-Generator und geben dem Seitenmodul den Name Job (da wir gerade die Details-Schaltfläche entsprechend konfiguriert haben, dass darüber zu dem Job-Seitenmodul verzweigt wird, haben wir keine große Wahl hier).

Und abschließend deselektieren Sie die Publiziert-Option von dem Seitenmodul, damit diese Job-Seite im WebSnap-Menü nicht sichtbar ist und der einzige Weg zum Erreichen der Seite über die Details-Schaltflächen führt.

Speichern Sie das resultierende WebSnap-Seitenmodul in der Datei pmJob.pas und drücken Sie Alt+F11 zum Hinzufügen der wDataMod-Unit zu dessen uses-Klausel, damit wir erneut alle DataSetAdapter von dem WebSnap-Datenmodul verwenden können. Beachten Sie, dass Sie - falls Sie es vergessen haben, zu deaktivieren - die Publiziert-Option im Initialisierungsabschnitt von dem generierten Quellcode jederzeit entfernen (oder hinzufügen) können (wpPublished sollte als Kommentar eingefügt sein):

initialization
if WebRequestHandler <> nil then
WebRequestHandler.AddWebModuleFactory(
TWebPageModuleFactory.Create(TJob,
TWebPageInfo.Create([{wpPublished} {wpLoginRequired}],
'.html'), crOnDemand, caCache));
end.

Sie können sowohl die wpPublished- als auch die wpLoginRequired-Option hier auskommentieren oder aktivieren, was sehr bequem ist.

Führen Sie einen Doppelklick auf den AdapterPageProducer aus, um den Editor für Web-Seiten zu starten. Führen Sie einen Rechtsklick auf dem AdapterPageProducer in dem Editor für Web-Seiten aus und ergänzen Sie eine AdapterForm. Unter der AdapterForm fügen Sie eine AdapterFieldGroup (für die Jobdetailinformation) als auch ein AdapterGrid (für die Angestellten) hinzu.

Um die zwei Designzeitwarnungen, die als Resultat der neuen Anzeigekomponenten auftauchen, zu beseitigen, lassen Sie die Adapter-Eigenschaft der AdapterFieldGroup auf WebDataModule1.dsaJOB zeigen und die Adapter-Eigenschaft von AdapterGrid auf WebDataModule1.dsaEMPJOB. Dies führt zu einer Ansicht, welche die Daten zur Designzeit erneut anzeigt (siehe Abbildung 3).


Abb.3: Der Editor für Web-Seiten bei der Ansicht von Jobs

Wenn Sie die Applikation kompilieren und laufen lassen, werden Sie keinen Menüeintrag für das neue Seitenmodul mit Namen Job sehen, aber wenn Sie zu Jobs gehen, werden Sie die Detail-Button in dem Gitter sehen und - wenn Sie auf eine Detail-Schaltfläche klicken - bei der Job-Seite für die ausgewählte Jobinformation enden.

Das Login
Lassen Sie uns nun Login-Support für unsere Applikation hinzufügen, indem wir sicherstellen, dass nur angemeldete Personen die Seiten hier sehen können. Dazu erweitern wir sie gleich mit spezifischen Zugriffsrechten.

Zuerst müssen wir ein neues WebSnap-Seitenmodul hinzufügen, das als Anmeldeformular verwendet wird. Wählen Sie also erneut Datei | Neu - Weitere aus und führen Sie einen Doppelklick auf das WebSnap-Seitenmodulsymbol aus. Selektieren Sie einen AdapterPageProducer und spezifizieren Sie den Namen für das neue Seitenmodul als Login. Ob Sie die Publiziert-Eigenschaft setzen oder nicht, können Sie selbst wählen (wenn sie gesetzt ist, wird die Anmeldeseite ebenso im horizontalen WebSnap-Menü auftauchen - im anderen Fall wird sie dort nicht angezeigt und dann bekommen Sie die Anmeldeseite nur dann zu sehen, wenn Sie versuchen, zu einem Seitenmodul zu gelangen, das die Option Anmeldung erforderlich gesetzt hat). Ich selbst habe die Publiziert-Eigenschaft übrigens nicht aktiviert.

Speichern Sie das resultierende WebSnap-Seitenmodul in der Datei pmLogin.pas. Aus dem WebSnap-Register der Komponentenpalette ziehen Sie eine TLoginFormAdapter-Komponente. TLoginFormAdapter ist eine spezielle WebSnap-Adapterkomponente, die die WebSnap-Loginfunktionalität für uns bereitstellt.

Führen Sie einen Rechtsklick auf dem LoginFormAdapter aus, um das Popupmenü aufzurufen, welches die Menüeinträge für den Adapter-Feld-Editor als auch den Adapter-Aktionseditor bereit stellt. Starten Sie zuerst den Adapter-Feld-Editor. Dort führen Sie einen Rechtsklick auf die Feldknoten aus und wählen Alle Felder hinzufügen. Dies resultiert in drei (default) Adapterfelder: AdaptUserName, AdaptPassword und AdaptNextPage. Die zuletzt Genannten werden in Kombination mit Seitenmodulen verwendet, welche die pmLoginRequired-Option definiert haben. Also müssen Sie sich zuerst anmelden (wenn Sie nicht schon angemeldet sind) und nach einer erfolgreichen Anmeldung werden Sie automatisch zum angegebenen Seitenmodul (dessen Wert als Next Page verwendet wird) weitergeleitet.


Abb. 4: Der Adapter-Feld-Editor

Da Sie die drei Adapter-Felder (siehe Abbildung 4) haben, können Sie diese selektieren und deren Caption-Eigenschaften verändern, um beispielsweise eine freundlichere Anmeldeseite zu erzeugen.

Wenn Sie das getan haben, wählen Sie den Feld-Editor, führen erneut einen Rechtsklick auf dem LoginFormAdapter aus und dieses Mal selektieren Sie den Aktionseditor. Führen Sie einen Rechtsklick auf Actions aus und wählen Sie dann Alle Aktionen hinzufügen, was zu der Erzeugung einer einzigen Aktion mit Namen ActionLogin führt. Erneut können Sie die Caption-Eigenschaft von dieser Komponente verändern, welche als die Beschriftung der Anmeldeschaltfläche später angezeigt wird.

Um den LoginFormAdapter zu verwenden, müssen wir einen Doppelklick auf dem AdapterPageProducer ausführen, um damit erneut den Editor für Web-Seiten zu aktivieren. Fügen Sie zuerst eine AdapterForm dem AdapterPageProducer hinzu (Sie sollten so langsam wissen, wie das geht) und dann eine AdapterErrorList, AdapterFieldGroup und AdapterCommandGroup unterhalb der AdapterForm. Setzen Sie die Adapter-Eigenschaft der AdapterErrorList und AdapterFieldGroup auf LoginFormAdapter und die DisplayComponent-Eigenschaft der AdapterCommandGroup auf die AdapterFieldGroup. Dies sollte alle Designzeitwarnungen beseitigen und Ihnen eine Designzeitvorschau des Anmeldeformulars geben (siehe Abbildung 5, welche das Anmeldeformular ohne irgendwelche Änderungen an den Caption-Eigenschaft der Login-Adapterfelder und -Aktion zeigt).


Abb. 5: Der Editor für Web-Seiten bei der Anzeige von Login

Beachten Sie die AdapterErrorList, welche eine neue Komponente ist, die Fehlermeldungen (wie unbekannte Anwendernamen oder falsche Passworte) anzeigen wird. Diese spezielle Anzeigekomponente kann mit jeder anderen Adapter-Komponente verbunden werden und ist also nützlich, um DataSetAdapter-Fehlermeldungen anzuzeigen (also sollten Sie eine AdapterErrorList vielleicht ebenso den vorherigen Seitenmodulen hinzufügen).

Anmeldung und Anwender
Da wir nun eine Anmeldeseite haben, ist es Zeit, dem Applikationsseitenmodul (in pmHome.pas) mitzuteilen, wo die Anmeldeseite zu finden ist. Dazu müssen wir einige ergänzende WebSnap-Komponenten dem Home-Seitenmodul hinzufügen. In der Grundeinstellung wird das WebSnap-Applikationsseitenmodul mit nur fünf Komponenten darauf generiert (siehe Abbildung 6): einen Default-PageProducer sowie eine WebAppComponents-, ApplicationAdapter-, PageDispatcher- und AdapterDispatcher-Komponente.


Abb. 6: Das Home-Seitenmodul

Damit die Anmeldung funktioniert (und mit Sitzungsinformationen verbunden werden kann), müssen wir drei neue Komponenten aus dem WebSnap-Register der Komponentenpalette ergänzen. Zuerst eine TendUserSessionAdapter, welche über eine Anmeldeeigenschaft verfügt, die auf den Namen von dem Anmeldeseitenmodul mit Namen Login gesetzt werden muss. Als zweites müssen wir eine TSessionServices-Komponente nehmen, um die Sitzungen in WebSnap zu verwalten.

Und abschließend gilt, dass ein reines Anmelden zwar nett ist, aber besser wäre es, wenn wir eine Liste mit berechtigten Usern zur Verfügung haben. Dafür ziehen wir eine TwebUserList-Komponente in das Modul. Führen Sie einen Rechtsklick auf diese letzte Komponente aus, um den Editor für Benutzerelemente aufzurufen, in dem Sie neue Anwender hinzufügen können. Für die kleine Demoapplikation in diesem Beitrag habe ich zwei Anwender definiert: Admin und Guest mit den Passworten admin und guest (nicht gerade sicher, aber Sie verstehen die Idee). Des Weiteren habe ich die AccessRights-Eigenschaft vom admin-User auf admin gesetzt (siehe Abbildung 7). Wir werden diese Eigenschaft im nächsten Abschnitt bei den WebSnap-Zugriffsrechten verwenden.


Abb. 7: Die WebUser-Liste

Das WebSnap-Applikationsseitenmodul sollte nun wie in Abbildung 8 aussehen (und beachten Sie, dass die WebAppComponents-Komponente automatisch seine Eigenschaften aktualisiert, wenn wir die neuen WebSnap-Komponenten darauf ziehen).


Abb. 8: Home Seitenmodul

Zum Test der Anmeldefunktionalität entfernen Sie den Kommentar der pmLoginRequired-Option in den pmJobs-, pmJob- und pmEmployees-Units, sodass diese Seitenmodule nun vom Anwender eine Anmeldung erfordern.

Sobald Sie auf eines der Seitenmodule mit der Login-Forderung klicken, wird das Anmeldeformular aufgeblendet, in dem Sie ihren Usernamen und das Passwort spezifizieren können. Beachten Sie ebenso, dass in der Grundeinstellung NextPage ein einzeiliges Listenfeld ist, das alle publizierten Seiten (aber nicht die nichtpublizierten Seiten) anzeigt.

Wenn Sie nicht wollen, dass NextPage als ein einzeiliges Listenfeld dargestellt wird, sondern als read-only-Anzeige, dann können wir zum pmLogin-Seitenmodul zurückgehen, den Editor für Web-Seiten aufrufen und die AdapterFieldGroup selektieren. Führen Sie einen Rechtsklick darauf aus und wählen Alle Felder hinzufügen zum expliziten Hinzufügen der drei Anzeigekomponenten für die Login-Adapterfelder. Selektieren Sie FldNextPage und verändern dessen ViewMode-Eigenschaft auf vmDisplay (diese wird Sie vor der Veränderung von diesem Wert bewahren).

Wenn Sie die Applikation erneut kompilieren und laufen lassen, werden Sie ein statisches Label sehen, wo vorher das Drop-Down-Listenfeld lokalisiert war. Dieses Mal kann der Anwender den Wert von dem NextPage-Feld nicht verändern. Genau wie gefordert. Dennoch gibt es Probleme - ein Bug wurde in Delphi 7 mitgeliefert, der dazu führt, dass der Wert von NextPage beim Login ignoriert wird. Nach der Anmeldung sind Sie immer noch auf der Anmeldeseite (wenn Sie sich korrekt angemeldet haben, können Sie nun aber zum Beispiel auf die Jobs-Seite klicken). Das ist ein spezifischer Bug in Delphi 7 - in Delphi 6 funktioniert das Verfahren korrekt.

Um dieses Problem zu beseitigen, kopieren Sie die Unit WebApt.pas in Ihr aktuelles Projektverzeichnis (beachten Sie, dass Sie das Projekt schließen und erneut öffnen sollten, damit Delphi bemerkt, dass es die WebAdapt.pas-Unit in dem Projektverzeichnis anstatt dem WebAdapt.dcu-File im Delphi7\Lib-Verzeichnis verwenden soll).

In WebAdapt.pas braucht die Methode TLoginFormAdapterLoginAction.ImplExecuteActionRequest einige Modifikationen. Die Veränderung sollte in Zeile 4985 beginnen, wo der folgende Code steht:

if Supports(WebContext.AdapterRequest, IGetAdapterRequestDefaultResponse,
DefaultResponse) then
NextPage := DefaultResponse.SuccessPage
else
NextPage := GetAdapterRequestParamsIntf(AActionRequest).ValueOfParam(sNextPage);

Dieses sollte so modifiziert werden:

NextPage := GetAdapterRequestParamsIntf(AActionRequest).ValueOfParam(sNextPage);
if (NextPage = '') and // no Next Page defined
Supports(WebContext.AdapterRequest, IGetAdapterRequestDefaultResponse,
DefaultResponse) then
NextPage := DefaultResponse.SuccessPage;

Zugriffsrechte
Da wir nun zwei verschiedene Anwender haben, lassen Sie uns die AccessRights-Eigenschaft verwenden, um sicher zu stellen, dass der Admin alles sehen und machen kann, wohin gegen ein Gast beschränkt ist (sowohl in Hinsicht darauf, was er sehen als auch tun kann). Erinnern Sie sich daran, dass die AccessRight-Eigenschaft des Admin-Users admin und vom Gastanwender leer ist. Die eigentliche Verwendung von dem Wert dieser Eigenschaft ist eine Zweischrittoperation. Zuerst müssen wir einige Aktionen auf den TDataSetAdapter-Komponenten bereitstellt und dann brauchen wir noch einige Optionen im AdapterPageProducer.

Lassen Sie uns zuerst mit den TDataSetAdapter-Komponenten beginnen. Gehen Sie also zu denwDataMod-WebSnap-Datenmodulen, führen Sie einen Rechtsklick auf dem dsaEMP-DataSetAdapter aus und starten den Adapter-Felder-Editor. Dort können Sie auf Feldknoten einen Rechtsklick ausführen und Alle Felder hinzufügen selektieren, um explizit persistente Adapter-Feld-Komponenten zu generieren. Jedes von diesen Adapterfelderern hat eine Eigenschaft mit Namen ViewAccess als auch eine Eigenschaft mit Namen ModifyAccess. Sie können einen Stringwert hier angeben, um zu bestimmen, wer Zugriff hat und wer nicht. Wenn der Stringwert, den Sie angegeben haben, Teil (oder vollständig) des Werts der AccessRights-Eigenschaft von dem gerade angemeldeten Anwender ist, dann wird der Zugang gewährt. Andernfalls wird der Zugang verweigert. Für AdaptHIRE_DATE, AdaptJOB_GRADE und AdaptSalary möchte ich die ViewAccess-Eigenschaft auf admin setzen, um zu gewährleisten, dass nur der Admin diese Felder sehen kann. Weiter will ich die ModifyAccess-Eigenschaft von allen Adapterfelder ebenso auf admin setzen, um sicher zu stellen, dass nur ein Admin diese verändern kann (und ein Gast nur deren Wert sehen, aber nicht verändern kann).

Schließen Sie nun den Adapter-Felder-Editor und führen Sie erneut einen Rechtsklick auf dem dsaEMP-DataSetAdapter aus - aber dieses Mal zum Starten von dem Adapter-Aktionseditor. Führen Sie einen Rechtsklick auf die Aktionsknoten aus und wählen Sie Alle Aktionen hinzufügen. Die Adapteraktionen haben eine verwandte Eigenschaft mit Namen ExecuteAccess, welche ich für die folgenden Aktionen auf admin setzen will: ActionDeleteRow, ActionEditRow, ActionNewRow, ActionCancel und ActionApply.

Wenn Sie ihre WebSnap-Applikation nun neu kompilieren und laufen lassen, werden Sie keinen Unterschied wahrnehmen. Unglücklicherweise hat Delphi die Geschichte etwas schwieriger gemacht, als es sein sollte: Wir müssen dem AdapterPageProducer mitteilen, dass die Werte der Zugriffseigenschaften bei Bedarf verwendet werden sollen und die Adapterfelder und -aktionen zu verstecken sind (wenn beispielsweise die Erlaubnis zur Ansicht verweigert wird, modifizieren Sie diese). Dazu müssen wir zum pmEmployees-Seitenmodul gehen und dort einen Doppelklick auf der TadapterPageProducer-Komponente ausführen, um den Editor für Web-Seiten zu starten. Selektieren Sie die AdapterFieldGroup, welche mit dem dsaEMP verbunden ist und führen Sie darauf einen Rechtsklick aus, um dann Alle Felderhinzufügen auszuwählen, damit alle persistenten Adapteranzeigefelder hinzugefügt werden. Wie Sie bemerken, gibt es reguläre Adapterfelder (mit Daten) und Adapteranzeigefelder (innerhalb des AdapterPageProducer). Die Letzteren sind für die Produktion von dem HTML-Code verantwortlich, den wir im Browser sehen. Und diese haben wir zu konfigurieren, ob sie diesen HTML-Code generieren sollen oder nicht. Für die Adapteranzeigefelder müssen wir explizit die Felder angeben, nach deren ViewAccess- und ModifyAccess-Eigenschaften zu schauen ist, indem die hoHideOnNoDisplayAccess-Untereigenschaft der HideOptions-Eigenschaft auf True gesetzt wird (aus verschiedenen Gründen ist der Vorgabewert dieser Eigenschaft False). Wir können das Gleiche für die CommandGroup machen, die mit den Adapteraktionen verbindet: setzen Sie deren bhoHideOnNoExecuteAccess-Untereigenschaft der HideOptions-Eigenschaft auf True.

Das wars! Es dauert aus meiner Sicher etwas länger als es im Grunde notwendig wäre, aber wenn Sie die Applikation nun speichern, kompilieren und laufen lassen, werden Sie bemerken, dass ein Admin alle Felder sehen und modifizieren sowie alle Aktionen ausführen kann, während ein Gast nur einige Felder sehen sowie nur einige Aktionen ausführen (nicht aber irgendein Feld modifizieren) kann. Genau wie wir es verlangt haben. Also ist es nun Zeit, die Webserver-Applikation für die endgültige Einrichtung im Web vorzubereiten.

Moving Target
Bis hierhin haben wir nur mit einer WebDebugger-Anwendung gearbeitet. Das bedeutet, wir können die Applikation aus der Delphi-IDE heraus starten und debuggen, aber wir können sie nicht im Internet einrichten. Dafür müssen wir die Applikation in eine andere Form wie ISAPI/NSAPI oder eine Apache-DLL überführen. Andernfalls werden Besucher nicht zum Login in Ihre Applikation in der Lage sein. Für jetzt werden wir die Applikation in eine ISAPI-DLL umwandeln und in einem Internet Information Server einrichten.

Glücklicherweise ist es nach all der Arbeit zum Erstellen der WebDebugger-Anwendung nur ein kleiner Schritt zum Überführen in eine andere Form. Zuerst müssen wir den Projektmanager aus dem Ansicht-Menü öffnen. Dann führen Sie einen Rechtsklick auf dem Wurzelknoten der ProjectGroup aus und wählen Neues Projekt hinzufügen" aus. Das wird ein neues Projekt der aktuellen Projektgruppe hinzufügen und die Objektgalerie aufrufen. Gehen Sie zur WebSnap-Seite der Objektgalerie und führen Sie einen Doppelklick auf dem WebSnap-Applikationssymbol aus. In dem folgenden Dialog selektieren Sie eine ISAPI/NSAPI-DLL und kümmern sich an der Stelle nicht um irgendwelche anderen Einstellungen.

Nachdem Sie auf die OK-Schaltfläche geklickt haben, erhalten Sie ein neues ISAPI/NSAPI-Projekt als auch ein WebSnap-Applikationsseitenmodul. Entfernen Sie das Seitenmodul aus dem Projekt (unter Verwendung vom Projektmanager) und speichern Sie dann die Projektdatei als ISAPI42.dpr (daraus entsteht beim Kompilieren ISAPI42.dll).

Innerhalb von dem Projektmanager müssen wir nun die WebSnap-Datenmodule und alle WebSnap-Seitenmodulen von der WAD-Applikation in das ISAPI/NSAPI-Ziel ziehen. Beachten Sie, dass Sie die WADForm nicht in Ihr ISAPI/NSAPI-Projekt integrieren sollten, da diese Datei das Hauptformular des WebApp-Debugger ist (welche im tatsächlichen Webserver-Projekt überflüssig ist). Für das Beispielprojekt müssen wir die Units pmHome, wDataMod, pmJobs, pmEmployees, pmJob und pmLogin in das neue Projekt ziehen. Dummerweise können Sie mehrere Dateien nicht auf ein Mal verschieben und nach jedem Drop einer Unit erhalten Sie einen Bestätigungsdialog, weshalb es etwas Zeit benötigt, alle Units dem neuen Projekt hinzuzufügen. Aber wenn Sie das erledigt haben, können Sie das neue ISAPI/NSAPI-Projekt kompilieren. Die gute Sache ist, dass beide Targets (WAD und ISAPI/NSAPI) nun die gleichen WebSnap-Module teilen. Wenn Sie also Veränderungen in den WebSnap-Datenmodulen oder Seitenmodulen durchführen, werden sich diese automatisch in beiden Varianten auswirken (Sie müssen sie nur - natürlich - beide neu kompilieren).

Einrichtung
Nach dem abschließenden Kompilieren von dem ISAPI/NSAPI-Projekt können wir die ISAPI42.dll im Scriptverzeichnis von dem IIS (Internet Information Services) Webserver oder PWS (Personal Web Server) von Microsoft einrichten. Unabhängig von dem Einrichten der ISAPI42.dll müssen wir ebenso alle HTML-Templatedateien mitliefern, die von Delphi generiert wurden. Für unser Projekt umfasst das pmHome.html, pmLogin.html, pmJobs.html, pmJob.html und pmEmployees.html. Diese fünf HTML-Dateien müssen in dem gleichen Verzeichnis platziert werden, wo sich die ISAPI42.dll befindet (generell das Scriptverzeichnis von Ihrem Webserver, aber es kann sich um jedes reale oder virtuelle Verzeichnis handeln, für das Ausführungsrechte gesetzt sind). Das Einrichten der HTML-Dateien im gleichen Verzeichnis stellt sicher, dass die Webserverapplikation sie findet (abwechselnd wollen Sie vielleicht die TLocateFileServices-Komponente verwenden - siehe in der Onlinehilfe für Details). Abschließend gilt bei der Verwendung von Delphi 6, dass Sie zwei Typelibraries mit Namen WebBrokerScript.tlb und stdvcl40.tlb registrieren müssen, die TRegSvr.exe verwenden (beachten Sie, dass diese für Delphi 7 WebSnap-Applikationen nicht mehr gebraucht werden).

Wenn Sie das alles getan haben, können Sie nun die ISAPI42.dll aus dem Browser nutzen und wenn vom Webserver die Verbindung zur Datenbank aufgebaut werden kann, werden Sie die gleiche Ausgabe wie zuvor sehen, aber dieses mal als real eingerichtete Webserverapplikation.

Nächstes Mal
In den letzten Beiträgen habe ich eine Menge über WebSnap und die Erstellung von mächtigen Webserverapplikationen geschrieben. Nichtsdestotrotz führte Delphi 7 ebenso ein anderes Webserver-Applikationsframework mit Namen IntraWeb ein. Und dieses wird das Hauptthema von einem weiteren Satz an Beiträgen, in denen ich zeige, dass IntraWeb für echte RAD-Webentwicklungen verwendet werden kann. Und keine Sorge, wenn Sie Zeit und Energie in WebSnap investiert haben, denn IntraWeb und WebSnap können perfekt zusammenarbeiten. Tatsächlich dreht sich der erste Artikel genau darum, gefolgt von einigen IntraWeb-Stand-alone-Applikationen. Bleiben Sie also dabei und bis zum nächsten Mal!

© 2004 Software & Support Verlag GmbH. Vervielfältigung nur mit Genehmigung des Verlags. Fragen?