Added more content to the tutorial

This commit is contained in:
Jocelyn Fiat
2012-05-25 22:55:15 +02:00
parent 6cff00428b
commit 08347da643
15 changed files with 322 additions and 26 deletions

View File

@@ -26,7 +26,7 @@ For now, you just need to know EWF is compliant with EWSGI specification.
Now let's discover the Eiffel Web Framework with this tutorial. Now let's discover the Eiffel Web Framework with this tutorial.
# [[step_1.wiki|Step #1]]: You will learn first, how to get and install EWF. # [[step_1.wiki|Step #1]]: You will learn first, how to get and install EWF.
# [[step_2.wiki|Step #2]]: build a simple Hello World application # [[step_2.wiki|Step #2]]: build a simple Hello World application
# [[step_3.wiki|Step #3]]: use the query and form parameter to build dynamic service # [[step_3.wiki|Step #3]]: use the parameter to build dynamic service
# [[step_4.wiki|Step #4]]: And you will learn how to dispatch URL # [[step_4.wiki|Step #4]]: And you will learn how to dispatch URL

View File

@@ -7,21 +7,16 @@
** [[step_1.wiki|Previous step]] completed ** [[step_1.wiki|Previous step]] completed
== Create "hello" project == == "hello" project ==
=== From the archive === * using the "wsf" library:
- to be completed ** It provides service, request, response, ...
* using the "default_nino" library
** This is used to build the application in a portable manner, but for this compilation, it uses Eiffel Web Nino as connector.
** We use Eiffel Web Nino for this tutorial, because there is no need to configure any apache, iis, and so on. And it is convenient to execute inside EiffelStudio
=== From the source === * You will find inside [[step_2]] the "hello" project
- Requirement: install git on your machine (http://www.git-scm.org/) ** target "hello" provides a very simple implementation (But by default, it is using port 80 with Eiffel Web Nino, which might already be busy by other application)
** target "hello_custom" which uses almost the same code, but in addition, you can use the ewf.ini file to precise the port number (9999 for this example)
git clone --recursive https://github.com/EiffelWebFramework/EWF.git ewf
And that's it for now.
== Install EWF ==
For now, there is nothing specific to do.
(Note: if you want to use the "http_client" library, you will need to do a few extra steps to eventually compile Eiffel Curl.)
---- ----
Previous [[step_1|step 1]] | Go to [[step_3.wiki|step 3]] Previous [[step_1|step 1]] | Go to [[step_3.wiki|step 3]]

View File

@@ -0,0 +1,11 @@
This folder contains 2 alternatives code
1) "execute" using the WSF_SERVICE interface, i.e
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
do
...
end
2) "launcher" using the WSF_RESPONSE_SERVICE interface, but it uses a launcher to start the service, instead of inheriting from WSF_DEFAULT_SERVICE or WSF_DEFAULT_RESPONSE_SERVICE

View File

@@ -0,0 +1,39 @@
note
description: "[
APPLICATION implements the `Hello World' service.
It inherits from WSF_DEFAULT_SERVICE to get default EWF connector ready
only `execute' needs to be implemented.
`initialize' can be redefine to provide custom options if needed.
]"
class
HELLO_APPLICATION
inherit
WSF_DEFAULT_SERVICE
create
make_and_launch
feature {NONE} -- Initialization
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
local
page: WSF_PAGE_RESPONSE
do
create page.make
page.put_string ("Hello World")
res.send (page)
--| another alternative would have been more low level
--| by setting the status code, the content type, and the content length which is 11 for "Hello World"
--| res.put_header ({WSF_HEADER}.ok, <<["Content-Type", "text/plain"], ["Content-Length", "11"]>>)
--| res.put_string ("Hello World")
end
end

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="hello_with_execute" uuid="DB6E98D3-64A9-4FF6-8F11-9E626DCAED6D">
<target name="hello_with_execute">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<root class="HELLO_APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<cluster name="src" location=".\" />
</target>
</system>

View File

@@ -8,23 +8,25 @@ note
]" ]"
class class
APPLICATION HELLO_APPLICATION
inherit inherit
WSF_DEFAULT_RESPONSE_SERVICE WSF_RESPONSE_SERVICE
redefine
initialize
end
create create
make_and_launch make_and_launch
feature {NONE} -- Initialization feature {NONE} -- Initialization
initialize make_and_launch
local
launcher: WSF_DEFAULT_SERVICE_LAUNCHER
opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS
do do
create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini") --| Uncomment the following line, to read options from "ewf.ini" configuration file
Precursor -- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} opts.make_from_file ("ewf.ini")
create launcher.make_and_launch (Current, opts)
end end
feature {NONE} -- Initialization feature {NONE} -- Initialization

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="hello_with_launcher" uuid="00871FE9-7114-4A09-BF4F-C0B833D4F1CB">
<target name="hello_with_launcher">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<root class="HELLO_APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<cluster name="src" location=".\"/>
</target>
</system>

View File

@@ -7,14 +7,18 @@
<exclude>/CVS$</exclude> <exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<root class="APPLICATION" feature="make_and_launch"/> <root class="HELLO_APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="wsf" location="..\..\..\..\library\server\wsf\wsf-safe.ecf"/> <library name="wsf" location="..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\library\server\wsf\default\nino-safe.ecf"/> <library name="default_nino" location="..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<cluster name="hello" location=".\" recursive="true"/> <cluster name="src" location=".\src" recursive="true"/>
</target>
<target name="hello_custom" extends="hello">
<root class="CUSTOM_HELLO_APPLICATION" feature="make_and_launch"/>
</target> </target>
</system> </system>

View File

@@ -0,0 +1,53 @@
note
description: "[
This class implements the `Hello World' service.
It inherits from WSF_DEFAULT_RESPONSE_SERVICE to get default EWF connector ready
only `response' needs to be implemented.
In this example, it is redefined and specialized to be WSF_PAGE_RESPONSE
`initialize' can be redefine to provide custom options if needed.
]"
class
CUSTOM_HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
redefine
initialize
end
create
make_and_launch
feature {NONE} -- Initialization
initialize
do
--| Uncomment the following line, to be able to load options from the file ewf.ini
-- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
--| You can also uncomment the following line if you use the Nino connector
--| so that the server listens on port 9999
--| quite often the port 80 is already busy
-- set_service_option ("port", 9999)
--| Uncomment next line to have verbose option if available
-- set_service_option ("verbose", True)
--| If you don't need any custom options, you are not obliged to redefine `initialize'
Precursor
end
feature {NONE} -- Initialization
response (req: WSF_REQUEST): WSF_PAGE_RESPONSE
-- Computed response message.
do
create Result.make
Result.put_string ("Hello World")
end
end

View File

@@ -0,0 +1,31 @@
note
description: "[
This class implements the `Hello World' service.
It inherits from WSF_DEFAULT_RESPONSE_SERVICE to get default EWF connector ready
only `response' needs to be implemented.
In this example, it is redefined and specialized to be WSF_PAGE_RESPONSE
`initialize' can be redefine to provide custom options if needed.
]"
class
HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
create
make_and_launch
feature {NONE} -- Initialization
response (req: WSF_REQUEST): WSF_PAGE_RESPONSE
-- Computed response message.
do
create Result.make
Result.put_string ("Hello World")
end
end

View File

@@ -1,2 +1,15 @@
= Tutorial Step 3 = [[README.wiki|Back to tutorial index]]
= Tutorial Step 3 =
* '''Goal''': Build Hello $user application using form parameter as input
* '''Requirements''':
** know how to compile with Eiffel (EiffelStudio).
** [[step_2.wiki|Previous step]] completed
== "hello" project ==
* Let's start from the "hello_custom" project
* you will learn how to use the req: WSF_REQUEST argument
----
Previous [[step_2|step 2]] | Go to [[step_4.wiki|step 4]]

View File

@@ -0,0 +1,4 @@
# For nino connector, use port 9999
port=9999
#verbose=true

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="hello" uuid="088E8D53-3705-4362-B04D-8EDF0DBE50E5">
<target name="hello">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<root class="HELLO_APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="wsf" location="..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<cluster name="src" location=".\src" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,83 @@
note
description: "[
This class implements the `Hello World' service.
It inherits from WSF_DEFAULT_RESPONSE_SERVICE to get default EWF connector ready
only `response' needs to be implemented.
In this example, it is redefined and specialized to be WSF_PAGE_RESPONSE
`initialize' can be redefine to provide custom options if needed.
]"
class
HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
redefine
initialize
end
create
make_and_launch
feature {NONE} -- Initialization
response (req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
-- Computed response message.
do
--| It is now returning a WSF_HTML_PAGE_RESPONSE
--| Since it is easier for building html page
create Result.make
Result.set_title ("EWF tutorial / Hello World!")
--| Check if the request contains a parameter named "user"
--| this could be a query, or a form parameter
if attached req.string_item ("user") as f_user then
--| If yes, say hello world #name
Result.set_body ("Hello " + f_user.string + "!")
--| We should html encode this name
--| but to keep the example simple, we don't do that for now.
else
--| Otherwise, ask for name
Result.set_body ("[
<form action="/" method="POST">
<p>Hello, what is your name?</p>
<input type="text" name="user"/>
<input type="submit" value="Validate"/>
</form>
]"
)
end
--| note:
--| 1) Source of the parameter, we could have used
--| req.query_parameter ("user") to search only in the query string
--| req.form_parameter ("user") to search only in the form parameters
--| 2) response type
--| it could also have used WSF_PAGE_REPONSE, and build the html in the code
--|
end
feature {NONE} -- Initialization
initialize
do
--| Uncomment the following line, to be able to load options from the file ewf.ini
create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
--| You can also uncomment the following line if you use the Nino connector
--| so that the server listens on port 9999
--| quite often the port 80 is already busy
-- set_service_option ("port", 9999)
--| Uncomment next line to have verbose option if available
-- set_service_option ("verbose", True)
--| If you don't need any custom options, you are not obliged to redefine `initialize'
Precursor
end
end