Skip to content

Commit

Permalink
Unified API for mapping static servlets #125
Browse files Browse the repository at this point in the history
docs
  • Loading branch information
andrus committed May 25, 2024
1 parent 4cc2298 commit 0973048
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,52 +89,36 @@ Listeners can rely on injection to obtain dependencies, just like servlets and f
=== Serving Static Files

Jetty is not limited to just servlets. It can also act as a webserver for static files stored on the filesystem or even
on the application classpath. By default this behavior is disabled to prevent unintended security risks. To enable the
"webserver" feature use extender's `useDefaultServlet()` method:
on the application classpath. To "publish" files in a given folder on Jetty, use the following API:

[source,java,indent=0]
----
include::../../../test/java/io/bootique/jetty/docs/ModuleWithDefaultServlet.java[tags=bindDefaultServlet]
include::../../../test/java/io/bootique/jetty/docs/StaticServlet.java[tags=staticServlet]
----

This enables a special internal servlet at "/" path, that will act as a static webserver. It requires an additional
configuration parameter though - the base directory where the files are stored. This is configured in YAML, and the path
can be either a directory on the filesystem or a classpath:
You can publish as many locations as needed. If a location is not known at compile time, it can alternatively
be defined in the app configuration with `resourceBase` servlet parameter:

[source,yaml]
----
jetty:
context: "/myapp"
staticResourceBase: "classpath:com/example/docroot"
servlets:
docroot:
params:
# This follows Bootique resource URL format
# and can be a "classpath:" URL or a filesystem path
resourceBase: "classpath:com/example/docroot"
----

"Default" servlet always has a base URL of "/" (relative to the application context). If you want a different path (or
need to serve more then one file directory under different base URLs), you can define more of those "webserver" servlets,
each with its own parameters:
Another potentially relevant (and rather confusing) setting is `pathInfoOnly`. It controls URL-to-file resolving
behavior and is available as a part of the location publishing API, or as a servlet parameter. E.g.:

[source,java,indent=0]
----
include::../../../test/java/io/bootique/jetty/docs/ModuleWithStaticServlets.java[tags=bindStaticServlets]
include::../../../test/java/io/bootique/jetty/docs/StaticServletPathInfo.java[tags=pathInfo]
----
By default each "static servlet" shares the common `staticResourceBase`, but it can also define its own base and
URL-to-file mapping approach using a
few https://www.eclipse.org/jetty/javadoc/9.4.19.v20190610/org/eclipse/jetty/servlet/DefaultServlet.html[servlet parameters],
namely `resourceBase` and `pathInfoOnly`:

[source,yaml]
----
jetty:
context: "/myapp"
servlets:
abc:
params:
# Note that "resourceBase" follows Bootique resource URL format
# and hence can be a "classpath:" URL or a filesystem path
resourceBase: "classpath:com/example/abcdocroot"
pathInfoOnly: true
----

`resourceBase` simply overrides `staticResourceBase` for a given servlet, while `pathInfoOnly` controls static resource
URL resolution as follows:
It behaves as follows:
|===
|URL|pathInfoOnly|File Path

Expand All @@ -147,6 +131,18 @@ URL resolution as follows:
|<resource_base>/dir1/f1.html
|===

Jetty `DefaultServlet` (the one serving the static files under the hood) supports a number of other
parameters https://eclipse.dev/jetty/javadoc/jetty-11/org/eclipse/jetty/servlet/DefaultServlet.html[described here].
Some of them, such as `relativeResourceBase`, require the app-wide resource base to be set:

[source,yaml]
----
jetty:
staticResourceBase: "classpath:com/example/docroot"
----

NOTE: `staticResourceBase` is really redundant in most (all?) situations, so hopefully you will never need to use it.

=== ServletEnvironment

Some application classes have direct access to the current servlet request and context (e.g. servlets, filters,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to ObjectStyle LLC under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ObjectStyle LLC licenses
* this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.bootique.jetty.docs;

import io.bootique.di.BQModule;
import io.bootique.di.Binder;
import io.bootique.jetty.JettyModule;
import io.bootique.jetty.MappedServlet;


public class StaticServlet implements BQModule {

// tag::staticServlet[]
@Override
public void configure(Binder binder) {
MappedServlet<?> s = MappedServlet
.ofStatic("docroot")
.urlPatterns("/")
.resourceBase("classpath:docroot")
.build();

JettyModule.extend(binder).addMappedServlet(s);
}
// end::staticServlet[]
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@
import io.bootique.di.BQModule;
import io.bootique.di.Binder;
import io.bootique.jetty.JettyModule;
import io.bootique.jetty.MappedServlet;

public class ModuleWithStaticServlets implements BQModule {

// tag::bindStaticServlets[]
public class StaticServletPathInfo implements BQModule {

@Override
public void configure(Binder binder) {
JettyModule.extend(binder)
.addStaticServlet("abc", "/abc/*")
.addStaticServlet("xyz", "/xyz/*");

// tag::pathInfo[]
MappedServlet<?> s = MappedServlet
.ofStatic("docroot")
.urlPatterns("/abc/*")
.pathInfoOnly()
.build();
// end::pathInfo[]

JettyModule.extend(binder).addMappedServlet(s);
}
// end::bindStaticServlets[]
}

0 comments on commit 0973048

Please sign in to comment.