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.
# [[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_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

View File

@@ -7,21 +7,16 @@
** [[step_1.wiki|Previous step]] completed
== Create "hello" project ==
=== From the archive ===
- to be completed
== "hello" project ==
* using the "wsf" library:
** 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 ===
- Requirement: install git on your machine (http://www.git-scm.org/)
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.)
* You will find inside [[step_2]] the "hello" project
** 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)
----
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
APPLICATION
HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
redefine
initialize
end
WSF_RESPONSE_SERVICE
create
make_and_launch
feature {NONE} -- Initialization
initialize
make_and_launch
local
launcher: WSF_DEFAULT_SERVICE_LAUNCHER
opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS
do
create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
Precursor
--| Uncomment the following line, to read options from "ewf.ini" configuration file
-- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} opts.make_from_file ("ewf.ini")
create launcher.make_and_launch (Current, opts)
end
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>/.svn$</exclude>
</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">
<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="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>
</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