|
|
(7 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
| + | [[Main_Page | Main page]] -> [[ICS_Components_Reference | ICS component reference]] -> [[THttpAppSrv | THttpAppSrv]] -> '''Tutorial''' |
| + | |
| == Description == | | == Description == |
| This tutorial is about writing a dynamic web application using THttpAppSrv component you can find in ICS version 7. | | This tutorial is about writing a dynamic web application using THttpAppSrv component you can find in ICS version 7. |
| | | |
| A dynamic web application is one which not only deliver static pages and files, but also dynamic web page. | | A dynamic web application is one which not only deliver static pages and files, but also dynamic web page. |
| + | |
| + | |
| + | == Source code == |
| + | * [{{SERVER}}/arch/OverbyteIcsTutWebAppServerLesson1to4.zip Lesson 1 to 4] |
| + | * [{{SERVER}}/arch/OverbyteIcsTutWebAppServerLesson1to6.zip Lesson 1 to 6] |
| | | |
| == Dynamic Pages == | | == Dynamic Pages == |
Line 18: |
Line 25: |
| Obvioulsy, you must have ICS-V7 installed within the IDE. When you install ICS, you usually add <ics installdir>\Delphi\VC32 to the compiler search path. If don't do that, you must add that path to every project. | | Obvioulsy, you must have ICS-V7 installed within the IDE. When you install ICS, you usually add <ics installdir>\Delphi\VC32 to the compiler search path. If don't do that, you must add that path to every project. |
| <br><br> | | <br><br> |
− | === Lesson 1 : Hello World === | + | == Lessons == |
− | | + | [[TutWebAppServer Lesson 1 - Hello World|Lesson 1 - Hello World]]<br> |
− | During this lesson, you will learn how to write the simplest website. The website you'll build has only one static page displaying "Hello World".
| + | [[TutWebAppServer Lesson 2 - Hello Today|Lesson 2 - Hello Today]]<br> |
− | | + | [[TutWebAppServer Lesson 3 - Simple data entry and processing|Lesson 3 - Simple data entry and processing]]<br> |
− | ==== Steps ====
| + | [[TutWebAppServer Lesson 4 - Building tables|Lesson 4 - Building tables]]<br> |
− | <ol>
| + | [[TutWebAppServer Lesson 5 - Relocation|Lesson 5 - Relocation]]<br> |
− | <li> Create a new VCL forms application.
| + | [[TutWebAppServer Lesson 6 - Simple login and session data|Lesson 6 - Simple login and session data]]<br> |
− | :: Here in the demo we use a classic GUI application. For a real application, it is likely that you'll create a service application.</li>
| + | [[TutWebAppServer Lesson 7 - Dynamic images|Lesson 7 - Dynamic images]]<br> |
− | <li> Rename the form "TutWebAppServerMainForm"</li>
| + | [[TutWebAppServer Lesson 8 - Asynchronous answer|Lesson 8 - Asynchronous answer]]<br> |
− | <li> On the form just created, drop a THttpAppSrv component.</li>
| |
− | <li> Save the files you have just created. Menu / File / Save all. Use OverbyteIcsTutWebAppServerMain.pas instead of unit1.pas and OverbyteIcsTutWebAppServer.dproj instead of project1.dproj.</li>
| |
− | <li> Hit F9 to compile and run the projet. You should get no error and a blank form. If you have errors, then it is likely you have ICS incorrectly installed. Terminate the application.</li>
| |
− | <li> Select the THttpAppSrv you just dropped on a form. Hit F11 to show the oject inspector and set a few property values:
| |
− | ::{|
| |
− | | Name || HttpAppSrv1
| |
− | |- | |
− | | Port || 20080
| |
− | |-
| |
− | | DocDir || c:\icstutorial\wwwroot
| |
− | |-
| |
− | | TemplateDir || c:\icstutorial\templates
| |
− | |-
| |
− | | DefaultDoc || index.html
| |
− | |}
| |
− | </li>
| |
− | <li> Create the document directory "c:\icstutorial\wwwroot" and the templates directory "c:\icstutorial\templates".</li>
| |
− | <li> Create our static html page: Menu / File / New / Others / Web document / HTML Page. Just enter the body text "Hello World" and save the file as "c:\icstutorial\wwwroot\index.html"</li>
| |
− | <li> Add a FormShow event handler to TutWebAppServerMainForm with the code:
| |
− | <tt>
| |
− | :: HttpAppSrv1.AddGetAllowedPath('/', afBeginBy);
| |
− | :: HttpAppSrv1.Start;
| |
− | </tt>
| |
− | </li>
| |
− | <li> Hit CTRL-SHIFT-S to save all.</li>
| |
− | <li> Hit F9 to compile and run the application. You still get an empty form, but actually you already have a web server running ! Depending on your OS and security settings, you may get a message asking you to block or allow the application. Be sure to allow it.</li>
| |
− | <li> Now enter the url: "http://127.0.0.1:20080" into your favorite browser. You should get your marvelous "Hello World" static page.</li>
| |
− | </ol>
| |
− | <br>
| |
− | ==== Summary ====
| |
− | In this lesson you learned how to build the basic webserver to serve static page. Beside the static pages you need, there are only two Delphi code lines to write.
| |
− | <br><br>
| |
− | === Lesson 2 : Hello Today ===
| |
− | | |
− | Let's add a dynamic webpage to our website. To make it simple, we will just display the current server date and time.
| |
− | | |
− | ==== Steps ====
| |
− | <ol>
| |
− | <li> Create the template for the dynamic web page: Menu / File / New / Others / web document / HTML Page.</li>
| |
− | <li> Write the text: "Server time is"</li>
| |
− | <li> Switch to the HTML code editor (ALT-PgUP or click "code" tab at bottom of the editor) to enter the special tag "<#DateTime>" where you want to have the date and time shown, that is just after "Server time is". You'll see that Delphi HTML editor add an ending tag we don't need. Just delete "</#DateTime>" Delphi has inserted.</li>
| |
− | <li> Save the template as "c:\icstutorial\templates\HelloToday.html"</li>
| |
− | <li> Now we must associate the processing required to build our dynamic webpage. This is done by creating a new class deriving from TUrlHandler. Menu / File / New / Other / Delphi Project / Delphi Files / Unit. Save this new unit as "OverbyteIcsTutWebAppServerHelloToday.pas". Enter this code into the unit:
| |
− | <tt>
| |
− | ::'''uses'''
| |
− | ::: SysUtils, OverbyteIcsHttpAppServer;
| |
− | <br> | |
− | ::'''type'''
| |
− | ::: TUrlHandlerHelloToday = '''class'''(TUrlHandler)
| |
− | ::: '''public'''
| |
− | :::: '''procedure''' Execute; '''override;'''
| |
− | ::: '''end;'''
| |
− | <br>
| |
− | ::'''implementation'''
| |
− | <br>
| |
− | ::'''procedure''' TUrlHandlerHelloToday.Execute;
| |
− | ::'''begin'''
| |
− | ::: AnswerPage(’’, ’’, 'HelloToday.html', nil, ['DateTime', DateTimeToStr(Now)]);
| |
− | ::: Finish;
| |
− | ::'''end;'''
| |
− | </tt>
| |
− | </li>
| |
− | <li> Switch back to OverbyteIcsTutWebAppServerMain and add "OverbyteIcsTutWebAppServerHelloToday" to the uses clause, add the following line in front of the FormShow event handler:
| |
− | ::<tt>HttpAppSrv1.AddGetHandler('/HelloToday.html', TUrlHandlerHelloToday);</tt></li>
| |
− | <li> Hit CTRL-SHIFT-S and F9 to save all, compile and run your application.</li>
| |
− | <li> Enter this URL into your browser: http://127.0.0.1:20080/HelloToday.html. You should see the web page as the template your designed with the tag "<#DateTime>" replaced by the date and time. Hit the refresh button several times to see the dynamic page in action: the time is the real time.</li>
| |
− | </ol>
| |
− | <br>
| |
− | ==== Summary ====
| |
− | In this lesson you learned how to write a template for a dynamic page, link the dynamic page URL to a Delphi class, write a Delphi class implementing the processing required to get data and feed it to the template.
| |
− | <br><br>
| |
− | === Lesson 3 : Simple data entry and processing ===
| |
− | During this lesson, you will learn how to present a data entry form to the user, process entered data and produce a result page. For simplicity, we will use a simple form to enter two numbers, an operator and provide the result in another simple page. Later, in another lesson, we will use AJAX to update the current page with the computation result.
| |
− | <br> | |
− | ==== Steps ====
| |
− | <ol>
| |
− | <li>Create a template HTML file for the calculator. Let's name that file SimpleCalculator.html and save it in the template folder we have located at "c:\icstutorial\templates". Menu / File / New / Others / Web documents / HTML page. Add the following HTML code as body:
| |
− | <tt>
| |
− | :: <form action="DoSimpleCalculator.html"
| |
− | :::: method="get"
| |
− | :::: enctype="application/x-www-form-urlencoded">
| |
− | ::: Number 1 <input name="Number1"><br>
| |
− | ::: Operator <select name="Operator">
| |
− | ::::: <option>Add</option>
| |
− | ::::: <option>Multiply></option>
| |
− | ::::: </select><br>
| |
− | ::: Number 2 <input name="Number2" type="TEXT"><br>
| |
− | ::: <input name="Submit" type="SUBMIT" value="Compute">
| |
− | :: </form>
| |
− | </tt></li>
| |
− | <li>Create a new unit to hold the calculator code. Menu / File / New / Delphi Unit. Save the unit as "OverbyteIcsTutWebAppServerSimpleCalculator.pas".</li>
| |
− | <li> Create the class to deliver the calculator's form. Actually we could have done a static page as well. Since we made a template, we need to write a class and map the class to the URL. The class and his implementation are quite straigthforward:
| |
− | <tt> | |
− | ::'''uses'''
| |
− | ::: SysUtils, OverbyteIcsHttpAppServer, OverbyteIcsHttpSrv;
| |
− | ::
| |
− | ::'''type'''
| |
− | ::: TUrlHandlerSimpleCaculator = '''class'''(TUrlHandler)
| |
− | ::: '''public'''
| |
− | :::: '''procedure''' Execute; '''override;'''
| |
− | ::: '''end;'''
| |
− | :::
| |
− | ::'''implementation'''
| |
− | ::
| |
− | :::'''procedure''' TUrlHandlerSimpleCaculator.Execute;
| |
− | :::'''begin'''
| |
− | :::: AnswerPage(’’, ’’, NO_CACHE, 'SimpleCalculator.html', nil, []);
| |
− | :::: Finish;
| |
− | :::'''end;'''
| |
− | </tt>
| |
− | </li>
| |
− | <li> Maping the class to the URL is done by calling AddGetHandler from TTutWebAppServerMainForm.FormShow. In order to reference the class, we must also add OverbyteIcsTutWebAppServerSimpleCalculator to the uses clause in OverbyteIcsTutWebAppServerMain.pas.
| |
− | <tt>
| |
− | ::: HttpAppSrv1.AddGetHandler('/SimpleCalculator.html', TUrlHandlerSimpleCaculator);
| |
− | </tt>
| |
− | </li>
| |
− | <li>At this stage, you can save all (CTRL-SHIFT-S), compile and run (F9) the application. Then point your browser to http://127.0.0.1:20080/SimpleCalculator.html. You should see the HTML form. If you click the Compute button, you get a 404 error since we have not implemented the form action yet. Let's do it. Stop the program and execute the next steps.</li>
| |
− | <li>Create the class to implement the calculator operation. In the HTML form above, we named the action "DoSimpleCalculator.html", so we will name the class "TUrlHandlerDoSimpleCalculator". We write the class in OverbyteIcsTutWebAppServerSimpleCalculator.pas unit. The declaration looks like:
| |
− | <tt>
| |
− | :: TUrlHandlerDoSimpleCalculator = '''class'''(TUrlHandler)
| |
− | :: '''public'''
| |
− | ::: '''procedure''' Execute; '''override;'''
| |
− | :: '''end;'''
| |
− | </tt></li>
| |
− | <li>Now write the code for the execute procedure. In this code we have to get the values entered by the user thru the HTML form we have designed. There are 3 fields we named "Number1", "Number2" and "Operator". The form definition specify method "get" and encoding "application/x-www-form-urlencoded". Those values directly impact how we received the values in Delphi. The HTTP server component unit has a function "ExtractURLEncodedValue" designed to get such value. It takes 3 arguments. The first is the parameters sent by the browser, the second is the name of the field and the third is a reference to the string variable to hold the result. The function return a boolean telling if the named parameter is found or not.<br>
| |
− | All in all we have to define 3 variable and call the method 3 times to get their values. Up to here, the code looks like:
| |
− | <tt>
| |
− | ::'''procedure''' TUrlHandlerDoSimpleCalculator.Execute;
| |
− | ::'''var'''
| |
− | ::: N1 : '''String''';
| |
− | ::: N2 : '''String''';
| |
− | ::: Op : '''String''';
| |
− | ::'''begin'''
| |
− | ::: ExtractURLEncodedValue(Params, 'Number1', N1);
| |
− | ::: ExtractURLEncodedValue(Params, 'Number2', N2);
| |
− | ::: ExtractURLEncodedValue(Params, 'Operator', Op);
| |
− | ::'''end''';
| |
− | </tt></li>
| |
− | <li>Now we have to do the computation. Be aware the every parameter is returned as a string. We have to do convertion to be able to compute the result. To hold the result, add an integer variable and name it "R". Add the fdollowing lines to the Execute procedure:
| |
− | <tt>
| |
− | :: '''if''' SameText(Op, 'Add') '''then'''
| |
− | ::: R := StrToInt(N1) + StrToInt(N2)
| |
− | :: '''else if''' SameText(Op, 'Multiply') '''then'''
| |
− | ::: R := StrToInt(N1) * StrToInt(N2)
| |
− | :: '''else'''
| |
− | ::: R := 0;
| |
− | </tt>
| |
− | For simplicity, we have not written any validation nor any exception handling. We are just demonstrating dynamic web design, not Delphi programmming best practices.</li>
| |
− | <li>To display the result, we have to prepare a HTML template and used it to send the answer page to the client's browser. Menu / File / New / Other / Web Document / HTML page. Name the file "SimpleCalculatorResult.html" and save it in the templates directory. As HTML body, write this HTML code:
| |
− | <tt>
| |
− | :: <#Operator>(<#Number1>, <#Number2>) = <#Result>
| |
− | :: <br><br>
| |
− | :: <a href="SimpleCalculator.html">Continue</a>
| |
− | </tt>
| |
− | This HTML code make use of 4 special tags named "Number1", "Number2", "Operator" and "Result". Those tags will be replaced by the actual values we provide by code when calling AnswerPage. The final code for the Execute procedure looks like this:
| |
− | <tt>
| |
− | ::'''procedure''' TUrlHandlerDoSimpleCalculator.Execute;
| |
− | ::'''var'''
| |
− | ::: N1 : '''String;'''
| |
− | ::: N2 : '''String;'''
| |
− | ::: Op : '''String;'''
| |
− | ::: R : '''Integer;'''
| |
− | ::'''begin'''
| |
− | ::: ExtractURLEncodedValue(Params, 'Number1', N1);
| |
− | ::: ExtractURLEncodedValue(Params, 'Number2', N2);
| |
− | ::: ExtractURLEncodedValue(Params, 'Operator', Op);
| |
− | ::: '''if''' SameText(Op, 'Add') '''then'''
| |
− | ::: R := StrToInt(N1) + StrToInt(N2)
| |
− | ::: '''else if''' SameText(Op, 'Multiply') '''then'''
| |
− | ::: R := StrToInt(N1) * StrToInt(N2)
| |
− | ::: '''else'''
| |
− | ::: R := 0;
| |
− | ::: AnswerPage(’’, NO_CACHE, 'SimpleCalculatorResult.html', nil,
| |
− | :::: ['Number1', N1, 'Number2', N2, 'Operator', Op, 'Result', R]);
| |
− | ::: Finish;
| |
− | ::'''end''';
| |
− | </tt>
| |
− | </li>
| |
− | <li>Finally, we have to map our class to an URL. This is done by calling AddGetHandler from TTutWebAppServerMainForm.FormShow.
| |
− | <tt>
| |
− | :::: HttpAppSrv1.AddGetHandler('/DoSimpleCalculator.html', TUrlHandlerDoSimpleCalculator);
| |
− | </tt>
| |
− | <li>Hit F9 to compile and run the application. Point your browser to http://127.0.0.1:20080/SimpleCalculator.html. You can enter values and submit. You should get the expected result page.</li>
| |
− | </ol><br>
| |