Servlet Mappings

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:

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.


Servlet Mapping Patterns

As described by the Java Servlet Specification, TiniHttpServer supports four types of servlet mappings: path-prefix mappings, extension mappings, default mapping, and exact mappings.

  1. Path-prefix mappings - Any mapping starting with a "/" and ending with a "/*" is a path-prefix mapping.

  2. Extension mappings - Any mapping starting with "*." is an extension mapping.

  3. Default mapping - A mapping that contains exactly "/" is the default mapping.

  4. 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.


Servlet Mapping Rules

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.

  1. If the request path exactly matches on of the exact mappings, that mapping is used.

  2. 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".

  3. If the request path ends with an extension mapping (not counting the mapping's leading "*"), that mapping is used.

  4. If none of the previous rules produce a match, the default mapping is used.


Configuring Servlet Mappings for TiniHttpServer

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.

General Format

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.

Example

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

Multiple Servlet Instances

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.

Example

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 Servlet Mappings

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.

Example

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

Specifying a Custom Default Servlet

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">

Example

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

The Default Default Servlet

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