public class StaticHandler extends Object implements HttpHandler
A StaticHandler maps a uriPrefix to a dirPrefix;
a URI with the uriPrefix is mapped to a file with the dirPrefix.
For example, if uriPrefix="/uri", dirPrefix="/dir",
the URI "/uri/x/y.txt" is mapped to the file "/dir/x/y.txt".
Each file can be configured individually by confMod.
See constructor StaticHandler(uriPrefix, dirPrefix, confMod).
URI encoding uses UTF-8 only; no other charset is supported.
A StaticHandler can be used directly for an HttpServer,
if the server serves nothing but static files.
More often, a StaticHandler is used in a parent handler that servers
both static files and dynamic contents. For example
StaticHandler staticHandler = new StaticHandler("/uri", "/dir");
HttpHandler appHandler = request ->
{
// try static files first
HttpResponseImpl resp = staticHandler.handle(request);
if(resp.statusCode()!=404) // 200, or other error codes
return resp;
// 404, request URI is not mapped to a static file
...
};
See handle(HttpRequest) for types of responses StaticHandler may generate.
StaticHandler supports tagged URI which embeds the
ETag of the file.
Response to a tagged URI never expires and can be cached forever.
For example, if currently ETag="v1.2.3" for file "/dir/css/main.css",
the tagged URI is "/uri/css/main.css?v1.2.3".
This URI can be obtained by staticHandler.uri("css/main.css").
// an html template
_link().rel("stylesheet").type("text/css").href( staticHandler.uri("css/main.css) )
The browser can request "/uri/css/main.css?v1.2.3" once and cache it forever.
When the ETag is changed (because the file is modified), a new tagged URI is generated,
and the browser will issue a new request to get the new content.
| Constructor and Description |
|---|
StaticHandler(String uriPrefix,
String dirPrefix)
Create a StaticHandler with default settings.
|
StaticHandler(String uriPrefix,
String dirPrefix,
ConsumerX<StaticFileConf> confMod)
Create a StaticHandler.
|
| Instance Methods | |
|---|---|
HttpResponseImpl |
handle(HttpRequest request)
Try to serve the request with a file response.
|
String |
uri(String relativeFilePath)
Get the URI for the file identified by
relativeFilePath. |
String |
info()
Return a text document listing all files and their metadata.
|
public StaticHandler(String uriPrefix, String dirPrefix) throws RuntimeException
See constructor
StaticHandler(uriPrefix, dirPrefix, confMod) for details.
RuntimeExceptionpublic StaticHandler(String uriPrefix, String dirPrefix, ConsumerX<StaticFileConf> confMod) throws RuntimeException
uriPrefix must be a valid URI path, starting with "/".
Examples: "/", "/uri", "/foo/bar".
dirPrefix must point to a directory.
Examples: "/dir", "../dir".
confMod is used to modify per-file config variables.
For each file under the directory, a StaticFileConf is created with default values,
then passed to confMod; confMod can modify any variables
in the StaticFileConf.
Example usage:
// map "/uri/xxx" to "/dir/xxx"; cache every file in memory.
static final StaticHandler staticHandler
= new StaticHandler("/uri", "/dir", conf->conf.cache(true) );
This constructor does blocking IO to read metadata of all files under the directory. That's not a problem if the static handler is created during application startup; but be careful if used in a non-blocking/async context.
RuntimeException - if something went wrong unexpectedly, for example file metadata cannot be read.public HttpResponseImpl handle(HttpRequest request)
If the request is GET/HEAD, and the URI maps to a file, a 200 response is returned to serve the file.
Other possible responses:
These error responses contain very simple text messages. If necessary (mostly for 404), the caller can transform the response to a better one.
This method always returns a new HttpResponseImpl which the caller can modify at will.
handle in interface HttpHandlerpublic String uri(String relativeFilePath) throws IllegalArgumentException
relativeFilePath.
relativeFilePath is relative to dirPrefix;
it must not start with "/" or "\"; it must not have been encoded with URI encoding.
This method has two purposes: to encode the URI, and to tag the URI.
For example, if
uriPrefix="/uri", dirPrefix="/dir",
uri("x/a b.txt") is mapped for file "/dir/x/a b.txt",
and the resulting URI is something like "/uri/x/a%20b.txt?t-53486116-314fb010".
relativeFilePath can also point to a directory that contains an
index file.
For example, uri("x") or uri("x/") means file "/dir/x/index.html",
uri("") means file "/dir/index.html".
IllegalArgumentExceptionpublic String info()
This is for diagnosis only. The document can be dumped on stdout, or served through a secret URL.
if(request.uri().equals(...))
return HttpResponse.text(200, staticHandler.info());