TiniHttpServer uses servlet mappings to determine how a request will be handled. TiniHttpServer versions 0.17 and beyond use a servlet mapping mechanism that is very different from the servlet mapping mechanism used in previous versions.
Prior to version 0.17, TiniHttpServer treated each request
in one of two ways: either it was a request for a servlet or
it was a request for a file. To determine whether a request
was to be handled by a servlet, pre-0.17 TiniHttpServer
looked for a single prefix (typically
"/servlet/
") in the request's
path. If this prefix was not found, the path was interpretted
as a request for a file. If this prefix was found, the next
element of the path was interpreted as the class name (or
class name alias) of the servlet which would handle the
request. A servlet was limited to a single instance
identified by its class name. This was not a very flexible
approach and not very conformant to the Java Servlet
Specification.
Starting with version 0.17, TiniHttpServer now conforms to the servlet mapping techniques described by The Java Servlet Specification, version 2.2. Additionally, TiniHttpserver now treats every request as a request for a servlet. In order to provide the file serving functionality expected from a web server, TiniHttpServer includes a default servlet that serves files just like the older versions of TiniHttpServer would do for non-servlet requests. These new features provide these new benefits:
Total control of which request paths map to which servlets.
Ability to load more than one instance of a servlet. This is most useful when combined with different inital arguments for each instance.
Ability to replace the default servlet to provide custom functionality for the "home page" and all other requests not explicitly handled by another servlet.
Servlet mappings are expressed as strings. The type of a servlet mapping is determined by matching it with a servlet mapping pattern. The servlet mapping patterns and the servlet mapping rules closely follow section 10.2 and 10.1, respectively, of The Java Servlet Specification, version 2.2. They are descibed below and followed by details on configuring servlet mappings for TiniHttpServer.
As described by the Java Servlet Specification, TiniHttpServer supports four types of servlet mappings: path-prefix mappings, extension mappings, default mapping, and exact mappings.
Path-prefix mappings - Any mapping starting with a
"/
" and ending with a
"/*
" is a path-prefix mapping.
Extension mappings - Any mapping starting with
"*.
" is an extension mapping.
Default mapping - A mapping that contains exactly
"/
" is the default mapping.
Exact mappings - Any other mapping starting with a
"/
" (but not ending with a
"/*
") is an exact mapping.
Any mapping not matching one of these patterns is invalid and will be ignored by TiniHttpServer.
When a request is received, TiniHttpServer matches the request's path (excluding any query string) with the servlet mappings according to the rules shown here. The first servlet mapping that matches the request's path is the mapping that is used, no further matches are attempted.
If the request path exactly matches on of the exact mappings, that mapping is used.
If the request path starts with one or more prefix
mappings (not counting the mapping's trailing
"/*
"), then the longest matching
prefix mapping is used. NOTE: Only complete path elements
are compared. For example,
"/foo/*
" will match (among
infinitely many others) "/foo
",
"/foo/
", and
"/foo/bar
", but will not match
"/foobar
".
If the request path ends with an extension mapping
(not counting the mapping's leading
"*
"), that mapping is used.
If none of the previous rules produce a match, the default mapping is used.
Servlet mappings are configured in the servlet properties
file. This file defaults to /etc/servlets.props
,
but can be changed in TiniHttpServer's optional
properties file. This file is also used to specify a servlet
instance's initial arguments and whether a servlet should
be preloaded at server startup or loaded on the first request
for it. The servlet properties file distributed with
TiniHttpServer includes mappings that are backwards
compatible with pre-0.17 versions of TiniHttpServer. Here are
the topics related to configuring servlet mappings:
NOTE: Your servlet must have a servlet mapping in the servlet properties file. If your servlet does not have a servlet mapping in the servlet properties file, it will not be accessible. Future versions of TiniHttpServer may include a configuration servlet that will allow you to alter the servlet mappings on the fly.
The general format for a servlet mapping is:
<name>.mapping=<mapping>
<name>.code=<classname>
<name>.initArgs=<inital arguments>
<name>.preload=<"true"|"false">
<name>
is the name given to an instance
of the servlet.
<mapping>
is a servlet mapping pattern
described above.
<classname>
is the fully qualified class
name of the servlet.
<initial arguments>
is a comma separated
list of "<key>=<value>
"
pairs.
Only the .mapping
line is required; the rest
are optional.
If the .code
line is omitted,
<name>
will be used for
<classname>
.
If the .initArgs
line is omitted, the
servlet has no initial arguments.
If the .preload
line is omitted, it
defaults to false.
The following example maps all requests starting with
"/foo
" to an instance of
FubarServlet
named
"foofoo
". The servlet has no initial
arguments and is not preloaded. Remember that prefix mappings
only match complete path elements. The mapping shown here
will match (among infinitely many others)
"/foo
",
"/foo/
", and
"/foo/bar
", but will not match
"/foobar
".
foofoo.mapping=/foo/*
foofoo.code=FubarServlet
As you can see, the servlet instance's name, is the common element relating the other properties. Multiple instances of the same servlet can be configured by associating multiple names with the same servlet class like this:
<nameA>.mapping=<mappingA>
<nameA>.code=<classname>
<nameA>.initArgs=<initial arguments for
<nameA> instance>
<nameB>.mapping=<mappingB>
<nameB>.code=<classname>
<nameB>.initArgs=<initial arguments for
<nameB> instance>
Notice that the <nameA>.code
and
<nameB>.code
refer to the same class.
The following example maps all requests starting with
"/foo
" to an instance of
FubarServlet
named
"foofoo
" and all requests starting
with "/bar
" to a different instance of
FubarServlet
named
"barbar
". The foofoo
instance, which is not preloaded, has the initial argument
named "problem
" with the value
"fouled up
". The barbar
instance, which is preloaded, has the initial argument named
"severity
" with the value
"beyond all repair
".
foofoo.mapping=/foo/*
foofoo.code=FubarServlet
foofoo.initArgs=problem=fouled up
barbar.mapping=/bar/*
barbar.code=FubarServlet
barbar.initArgs=serverity=beyond all repair
barbar.preload=true
Multiple mappings for the same servlet instance can also be configured by using the following syntax:
<name>.mapping=<mapping>
<name>.code=<classname>
<name>.initArgs=<inital arguments>
<alias0>.mapping=<mapping0>
<alias0>.name=<name>
<alias1>.mapping=<mapping1>
<alias1>.name=<name>
<aliasN>.mapping=<mapping2>
<aliasN>.name=<name>
<aliasN>.initArgs=<ignored initial arguments, see comment below>
Initial arguments are based on the servlet instance's
name. Initial arguments are not based on any alias. Any
"<alias>.initArgs
" line will be
ignored.
The following example maps all requests starting with
"/foo
" or "/fu
"
to an instance of FubarServlet
named
"foofoo
". The foofoo
instance has the initial argument "problem=fouled
up
" and is not preloaded.
foofoo.mapping=/foo/*
foofoo.code=FubarServlet
foofoo.initArgs=problem=fouled up
fufu.mapping=/fu/*
fufu.name=foofoo
It is not necessary to specify a default servlet because
TiniHttpServer includes a default servlet that will be used
if no other default servlet is specified (a default default
servlet). You may, however, use any servlet to handle
requests that are not handled by any other servlet. To do
this, simply associate the default mapping of
"/
" to a servlet instance of your
choice like this:
<name>.mapping=/
<name>.code=<classname>
<name>.initArgs=<inital arguments>
<name>.preload=<"true"|"false">
The following example will configure an instance of
servlet class MyDefaultServlet
to be the default
servlet. The instance in this example happens to be named
"defaultServlet
".
defaultServlet.mapping=/
defaultServlet.code=MyDefaultServlet
In addition to the default servlet itself, TiniHttpServer
includes a default name and mapping for one instance of the
default server. In the absence of an explicit default servlet
mapping, the name of the default default servlet's
instance is the same as the class name of the default default
servlet, which is
com.smartsc.http.DefaultServlet
. This servlet
will treat the request as a request for a file from the file
system under the directory (typically
"/docs
") specified by the
server.docRoot
property in ther server properties file. If the
file specified by the request path is a directory, the
default servlet will send the index file from that directory
to the client. The name used for the index file is typically
"index.html
", but this can be changed
in the servlets properties file by specifying a value for the
"indexFile
" inital argument for the
com.smartsc.http.DefaultServlet
servlet
instance. For example, to set the index file to
"home.html
", add the following line to
the servlet properties file:
com.smartsc.http.DefaultServlet.initArgs=indexFile=home.html
Copyright © 1999-2002 Smart Software Consulting