zhxy/http服务器/appweb-4.3.4-0/doc/guide/esp/users/using.html

411 lines
26 KiB
HTML

<!-- BeginDsi "dsi/head.html" -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Embedthis Appweb 4.3.4 Documentation</title>
<meta name="keywords" content="embedded web server, web server software, embedded HTTP, application web server,
embedded server, small web server, HTTP server, library web server, library HTTP, HTTP library" />
<meta name="description" content="Embedthis Sofware provides commercial and open source embedded web servers for
devices and applications." />
<meta name="robots" content="index,follow" />
<link href="../../../doc.css" rel="stylesheet" type="text/css" />
<link href="../../../print.css" rel="stylesheet" type="text/css" media="print"/>
<!--[if IE]>
<link href="../../../iehacks.css" rel="stylesheet" type="text/css" />
<![endif]-->
<link href="http://www.google.com/cse/style/look/default.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div class="top">
<a class="logo" href="http://appwebserver.org/">&nbsp;</a>
<div class="topRight">
<div class="search">
<div id="cse-search-form"></div>
<div class="version">Embedthis Appweb 4.3.4</div>
</div>
</div>
<div class="crumbs">
<a href="../../../index.html">Home</a>
<!-- EndDsi -->
&gt;<a href="index.html">ESP Guide</a> &gt; <b>Embedded Server Pages</b>
</div>
</div>
<div class="content">
<div class="contentRight">
<h1>Quick Nav</h1>
<ul class="nav">
<li><a href="#router">Request Router</a></li>
<li><a href="#caching">Response Caching</a></li>
<li><a href="#handler">ESP Handler</a></li>
<li><a href="#mvc">Model-View-Controller</a></li>
<li><a href="#views">Views</a></li>
<li><a href="#pipeline">Pipeline</a></li>
<li><a href="#layouts">Layouts</a></li>
<li><a href="#controllers">Controllers</a></li>
<li><a href="#actions">Actions</a></li>
<li><a href="#api">ESP API</a></li>
<li><a href="#compiler">Compiler</a></li>
<li><a href="#generator">ESP Generator</a></li>
<li><a href="#models">Models</a></li>
<li><a href="#deployment">Deployment</a></li>
</ul>
<!-- BeginDsi "dsi/webFrameSeeAlso.html" -->
<h1>See Also</h1>
<ul class="nav">
<li><a href="../../../guide/appweb/users/frameworks.html">Web Frameworks</a></li>
<li><a href="../../../guide/appweb/users/action.html">Action Handler</a></li>
<li><a href="../../../guide/appweb/users/cgi.html">CGI</a></li>
<li><a href="../../../guide/esp/users/index.html">ESP</a></li>
<li><a href="../../../guide/appweb/users/ejs.html">Ejscript</a></li>
<li><a href="../../../guide/appweb/users/php.html">PHP</a></li>
<li><a href="../../../guide/appweb/users/index.html">User Guide Overview</a></li>
<li><a href="../../../guide/appweb/users/configuration.html">Configuring Appweb</a></li>
<li><a href="../../../guide/appweb/users/ports.html">Ports and Binding</a></li>
<li><a href="../../../guide/appweb/users/authentication.html">User Authorization</a></li>
<li><a href="../../../guide/appweb/users/logFiles.html">Log Files</a></li>
<li><a href="../../../guide/appweb/users/vhosts.html">Virtual Hosts</a></li>
<li><a href="../../../guide/appweb/users/security.html">Security Considerations</a></li>
<li><a href="../../../guide/appweb/users/ssl.html">SSL</a></li>
<li><a href="../../../guide/appweb/users/modules.html">Appweb Modules</a></li>
<li><a href="../../../guide/appweb/users/stages.html">Pipeline Stages</a></li>
<li><a href="../../../guide/appweb/users/client.html">HTTP Client</a></li>
<li><a href="../../../ref/appweb/architecture.html">Appweb Architecture</a></li>
</ul>
<!-- EndDsi -->
</div>
<div class="contentLeft">
<h1>Embedded Server Pages</h1>
<p>The Embedded Server Pages (ESP) web framework makes it dramatically easier to create blazing fast
dynamic web applications. The ESP web framework provides an application generator, templating engine, a powerful
Model-View-Controller framework, a library of HTML controls and an extensive API to take the tedium out
of creating web applications. Via this framework, ESP drastically reduces the number of lines of code you
need to write for a compelling, dynamic web application.</p>
<p>This document describes the ESP web framework and how ESP is embedded in Appweb to run web applications
and respond to web requests. It describes the flow of execution and the main processing components. NOTE:
ESP is integrated into Appweb and is not a separate product. Appweb includes the ESP web framework and esp
handler.</p>
<p>See also the <a href="tour.html">ESP Framework Tour</a>.</p>
<h2 class="section">ESP Web Framework Architecture</h2>
<p>ESP uses the "C" language for server-side web programming coupled with a garbage-collected environment
for safe programming. This enables unparalleled performance in secure environment for web applications. </p>
<p>The ESP web framework provides a complete set of components including: a web request handler,
templating web engine, a Model/View/Controller application framework and an edit-and-continue
development model.</p>
<img src="../../../images/espArchitecture.jpg" alt="ESP Web Framework Architecture" />
<p>The main components of the Appweb ESP Web Framework are:</p>
<ul>
<li><a href="#router">Request Router</a> &mdash; Parse requests and route to the appropriate handler</li>
<li><a href="#caching">Caching</a> &mdash; Appweb response caching</li>
<li><a href="#handler">ESP Handler</a> &mdash; ESP request handler</li>
<li><a href="#mvc">ESP MVC</a> &mdash; ESP Model-View-Controller framework</li>
<li><a href="#views">ESP Views</a> &mdash; ESP Views and web page templates</li>
<li><a href="#controllers">ESP Controllers</a> &mdash; ESP Controllers and Actions</li>
<li><a href="#api">ESP Programmers Interface (API)</a> &mdash; Extensive control API</li>
<li><a href="#compiler">"C" compiler</a> &mdash; Compile ESP pages, controllers and applications</li>
<li><a href="#generator">ESP Generator</a> &mdash; Generate applications, controllers and scaffolds</li>
</ul>
<a id="router"></a>
<h2 class="section">Request Routing</h2>
<p>Appweb includes a powerful request routing engine that processes client HTTP requests. The engine is
configured with a set of routes and when a request is received, it examines various routes and selects the best
to handle the request. In the process, routes may redirect or rewrite the request as required.</p>
<p>ESP relies on this routing engine to parse request URIs into tokens that determine how a request should
be handled. Of particular importants, the routing engine determines the if an ESP controller needs to be
activated to respond to the request and what ESP view page to serve.</p>
<p>ESP eschews "ugly" long URIs that are gibberish to users and instead actively encourages human readable URIs
that represent the resource being requested. The request router is essential to support this.</p>
<a id="caching"></a>
<h2 class="section">Response Caching</h2>
<p>Pages that are slow to render and general slow network transmission can have large detrimental
effect on the usability of a web application. Caching client response data is an ideal and simple technique
for speeding up slow web pages. </p>
<p>Web pages that are frequently used, but slow to render are ideal candidates to be cached.
Images that rarely change are also good to cache. When such resources are cached at the server,
client responses are served directly from the cache without invoking the handler to render the page. This
often results in dramatic performance gains. Further, if the Appweb caching is configured to also cache at the
client, the Appweb cache cooperates with the client-side cache so the content itself may not need
to be resent to the client. See the <a href="../../appweb/users/caching.html">Appweb Response Caching</a>
for more details.</p>
<a id="handler"></a>
<h2 class="section">ESP Handler</h2>
<p>Appweb hosts the ESP handler via a loadable module called <em>mod_esp</em>. This is an optional
Appweb module that includes the ESP web framework. The module is configured by directives in the
<em>appweb.conf</em> configuration file. ESP applications will typically define an Appweb route
for the application via the EspApp directive. For example:</p> <pre>
EspApp /store/ /Directory/to/storeApp restful sqlite://app/db/store.sdb
</pre>
<p>This instructs Appweb to send all requests with the URI prefix "myAppName" to ESP for
routing and processing.</p>
<a id="mvc"></a>
<h2 class="section">Model-View-Controller</h2>
<p>A Model-View Controller-framework, also known as MVC, is a proven paradigm for organizing web
applications. The model manages the state of the application including the database. The controller manages
the application, responding to inputs and invokes the relevant views to generate the user interface.</p>
<p>Originally developed in the '70s, it has been more recently adapted for web applications and been
popularized by frameworks such as <a href="http://www.rubyonrails.org">Ruby on Rails</a>. ESP uses the
same paradigm with an embedded spin.</p>
<p>The ESP web framework supports two application paradigms, that
can be combined in a single application if desired:</p>
<ul>
<li>ESP Model-View-Controller Applications</li>
<li>Stand-alone ESP web pages</li>
</ul>
<h3>ESP Pages</h3>
<p>An ESP page is a HTML web page with embedded "C" code that executes at run-time to dynamically create a
client response. The pages typically have a <em>.esp</em> extension and may use ESP template layout pages to
define the look and feel of the application. They do not use the full Model-View-Controlller paradigm, nor
do they use the ESP <em>esp</em> application generator. ESP pages often use a simple "Post-Back" paradigm
where form data is posted back to the same page.</p>
<p>ESP MVC applications are more powerful and and better suited for creating web applications. They provide
more structure to support the application by providing database models, controllers and actions. They combine
these with ESP templates and ESP pages for a complete web framework.</p>
<a id="views"></a>
<h2 class="section">ESP Views</h2>
<p>The View part of the ESP web framework is responsible for generating the user interface. Views are
typically created via ESP web pages. However, they can also be generated by controllers without an ESP
page.</p>
<p>ESP Views provide:</p>
<ul>
<li>Embedded "C" language code for dynamic HTML responses</li>
<li>A rich ESP API library to render output</li>
<li>Layout pages for consistent UI look and feel</li>
<li>Support for client-side JavaScript and AJAX via jQuery integration</li>
<li>A suite of HTML controls such as table, chart, tab, and tree</li>
</ul>
<a id="pipeline"></a>
<h3>View Pipeline</h3>
<p>The ESP View mechanism consists of a processing pipeline that progressively transforms the web page. Views
start with a partial HTML view page which typically, though not always, contains embedded "C" code. This is
parsed by the ESP Template Engine and combined with layout views to create a single composite web page.
This is then converted to pure "C" code that is compiled, linked and saved as a native-code shared library. </p>
<img src="../../../images/esp/template/layout.jpeg" alt="View Pipeline" />
<a id= "layouts"></a>
<h3>Layout Pages</h3>
<p>Layout pages are an important part of a view framework. They allow you to specify the UI "look
and feel" and standard components of a web application in one place. Content pages can then reuse the
"look and feel" in by simply referencing a layout page.</p>
<p>The layout page is structurally just an ESP Page that typically contains the top level HTML
structure, style sheets and graphic content that is standard on every page. It may contain embedded "C"
code, and most importantly, it specifies the location to insert content from content pages.</p>
<p>The content pages focus on the content and data that is unique to that page. Content pages
do not replicate the layout and look and feel that is specified in the layout page. In this way, changing
the layout page in once place will automatically change every web page in the application.</p>
<p>Here is a simple layout page:</p>
<pre>
&lt;html&gt;
&lt;body&gt;
&lt;img src="banner.jpg"&gt;
<b>&lt;%@ content %&gt;</b>
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The <b>&lt;%@ content %&gt;</b> directive instructs the Template Engine to insert the content page at
this location. </p>
<p>Here is a simple content page:</p>
<pre>
&lt;h1&gt;Hello World&lt;/h1&gt;
&lt;p&gt;Today is &lt;%= mprGetDate(0) %&gt;
</pre>The Template Engine supports the following web page directives. These can be used in layout or content pages:
<pre class="light">
&lt;% "C" language code %&gt;
&lt;%= "C" string expression %&gt;
&lt;%@ include "filename" %&gt;
&lt;%@ layout "file" %&gt;
@!variable
@@param
@#field
</pre>
<p>The &lt;% "C" code %&gt; directive will insert the given code at this location. At run-time, this
code will execute. A typical use of this directive is to call
<a href="../../../api/esp.html#group___esp_abbrev_1gaf89154adc3cbf6d6a6a32c6b4457c593">render</a> to write
data back to the client at this position in the web page.</p>
<p>The &lt;%= "C" expression %&gt; directive will evaluate the expression and substitute the resulting
string value into the web page.</p>
<p>The @!variable directive is a shortcut for &lt;%= expression %&gt;.</p>
<p>The @@param directive substitutes the value of a request parameter or session variable of the same
name after HTML escaping the value.</p>
<p>The &lt;% include "filename" %&gt; directive will include the given file name at the location of the
directive when parsing the web page. Included files may contain ESP directives and
include directives can be nested.</p>
<p>The &lt;%@ layout "file" %&gt; directive specifies the name of the layout page. By using this directive
in layout pages, you can build up the web page layout by nesting layout pages. If omitted in content pages,
which is usually the case, the default layout of <em>layouts/default.esp</em> will be used.
If omitted in layout pages, it is assumed the layout page is the top level layout page.</p>
<p>The web parser supports the following web page directives in layout pages:</p>
<pre class="light">&lt;%@ content %&gt;</pre>
<p>This specifies the location for the content page data.</p>
<p>Note: you do not have to use layout pages. Simple stand-alone web pages without layouts code are
supported. To disable use of a layout page, use a <em>&lt;%@ layout="" %&gt;</em> directive.</p>
<h3>HTML Controls</h3>
<p>The ESP web framework provides a suite of view controls for common UI elements. These include button, chart,
checkbox, form, image, label, link, list, progress bar, radio button, table, tabs, text, textarea and tree.
The controls are a themeable and skinnable set of UI controls that provides a higher
level of functionality than bare HTML. For example, the table control allows the easy display of database
data with sortable rows and selectable columns.</p>
<p>Some of the controls are bindable to database data and many controls can dynamically refresh their
content using Ajax techniques without redisplaying the entire page.</p>
<a id="controllers"></a>
<h2 class="section">Controllers - Responding to Requests</h2>
<p>Controllers are the heart of ESP MVC applications. They manage the application's response to client
requests. Different controllers are typically bound to various URIs so that user requests are routed to
specific actions within the appropriate controller.</p>
<a id="actions"></a>
<h3>Actions</h3>
<p>When Appweb receives a request to service, it is dispatched to the action function after loading the
appropriate controller. The job of the action function is to:</p>
<ol>
<li>Respond to the request</li>
<li>Render a response view back to the client</li>
</ol>
<p>The action responds to the request depending on the request parameters that include the request
query information, form parameters and other Http and application state information.</p>
<p>Here is a sample action function that updates a database table based on user submitted form data in
"params".</p>
<pre>
static void update() {
if (updateFields("post", params())) {
inform("Post updated successfully.");
redirect("@");
} else {
renderView("post-edit");
}
}
</pre>
<p>An action function can explicitly render data by calling one of the
<a href="../../../api/esp.html#group___esp_abbrev_1gaf89154adc3cbf6d6a6a32c6b4457c593">render</a> methods.
It can redirect the client to a new URI via the
<a href="../../../api/esp.html#group___esp_abbrev_1ga79cf206805a9595395af14e7c35f289d">redirect</a> method.
Manual rendering is ideal for RESTful web services, particularly when coupled with the the XML and JSON
capabilities of Appweb.</p>
<p>If the action method does not explicitly render any data, the web framework will automatically render an
ESP web page of the same name as the action function. That web page has full access to the controller and request
state.</p>
<a id="api"></a>
<h2 class="section">ESP API</h2>
<p>The ESP web framework has an extensive suite of APIs to cover all possible design needs. It also
defines an expressive, terse, short-form API that makes common tasks simple.
See the <a href="../../../api/esp.html">ESP API Reference</a> for more details.</p>
<a id="compiler"></a>
<h2 class="section">C Compiler</h2>
<p>To compile ESP pages and controllers into native code for execution, a "C" language compiler is required.
When developing, the compiler is used to transparently compile and recompile ESP pages and controllers as
they are modified on disk. This results in a set of shared-library files that represent the ESP application. </p>
<h3>Deployment</h3>
<p>To deploy this application, only the library files are required. The source code for the ESP pages and
controllers is typically not deployed. Of course, if you wish to continue to provide transparent compilation once
deployed, then include the source and set <em>EspUpdate on</em> in the appweb.conf configuration file.</p>
<p>The <em>esp</em> generator program can also be used to compile an ESP application including all ESP
pages and controllers into a single shared library file. This is an ideal and simple way to deploy an ESP
application.</p>
<h3>Cross Compilation</h3>
<p>When cross-compiling, prepare a version of the appweb.conf and esp.conf configuration files for your
target. This means editing the <em>esp.conf</em> file to define the appropriate compilation command line
for your target. Then invoke <em>esp --config cross.conf compile ...</em> to cross compile the ESP pages
and controllers.</p>
<a id="generator"></a>
<h2 class="section">ESP Generator</h2>
<p>The ESP framework includes a utility program to generate new applications, scaffolds, controllers,
and views. This program is called <em>esp</em> and automates many common tasks when dealing with MVC
applications.</p>
<p>To create a new application called demo:</p>
<pre>
esp generate app demo
</pre>
<p>This will create the following directories:</p>
<ul>
<li>demo/cache</li>
<li>demo/controllers</li>
<li>demo/db</li>
<li>demo/layouts</li>
<li>demo/static</li>
<li>demo/views</li>
</ul>
<p>It will also create the following files (among others):</p>
<ul>
<li>test/app.conf</li>
<li>test/appweb.conf</li>
<li>test/esp-app.h</li>
<li>test/layouts/default.esp</li>
</ul>
<p>The <em>esp</em> program creates the application directory and populates it with the necessary
directories, configuration files and stubs to begin the application.</p>
<p>When you run Appweb, ESP will automatically compile and load MVC components as required. You can also
pre-compile your entire application from the application directory via:</p>
<pre>
esp compile
</pre>
<a id="models"></a>
<h2 class="section">Models</h2>
<p>The Model part of an MVC framework typically provides an Object Relational Mapping (ORM) layer.
Unfortunately, while being powerful and extensive, these often consume considerable amounts of memory and
can be slow at run-time. ESP avoids this problem by providing a simple mapping from relational database data
to "C" based records and grids. This results in a high-performance database interface with very low
memory requirements.</p>
<h3>Embedded Database Interface</h3>
<p>ESP supports an Embedded Database Interface (EDI) above a selectable database backend such as:
SQLite, MySQL and MDB. The MDB database is a tiny, in-memory database &mdash; great for embedded applications.
SQLite is a full SQL implementation for embedded applications, while MySQL is an enterprise class SQL
server. MDB is the smallest and fastest, but has the least features.</p>
<a id="deployment"></a>
<h2 class="section">Development and Deployment</h2>
<p>There are two phases of use for ESP: </p>
<ul>
<li>Development</li>
<li>Deployment</li>
</ul>
<h3>Development</h3>
<p>When developing, developers need
quick turn-around with rapid test-modify-build cycles. ESP supports and edit-and-continue style of
development where modified ESP pages are transparently recompiled and reloaded. There is no explicit
compilation step required. Simply reloading an ESP page in the browser will trigger the changed page to be
rebuilt. This supports iterative development styles such as <a href=
"http://en.wikipedia.org/wiki/Agile_software_development">Agile Web Development</a>. </p>
<h3>Deployment</h3>
<p>When ready for deployment, the entire application can be compiled into a single shared library file for easy
deployment.</p>
</div>
</div>
<!-- BeginDsi "dsi/bottom.html" -->
<div class="bottom">
<p class="footnote">
<a href="../../../product/copyright.html" >&copy; Embedthis Software LLC, 2003-2013.
All rights reserved. Embedthis, Appweb, ESP, Ejscript and Embedthis GoAhead are trademarks of Embedthis Software LLC.</a>
</p>
</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1', {language : 'en'});
google.setOnLoadCallback(function() {
var customSearchControl = new google.search.CustomSearchControl(
'000262706376373952077:1hs0lhenihk');
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var options = new google.search.DrawOptions();
options.enableSearchboxOnly("http://appwebserver.org/search.html");
customSearchControl.draw('cse-search-form', options);
}, true);
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-179169-2']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>