Class StaticFilesMixin
StaticFiles implementation under
/static/* (configurable).
Wraps the existing BasicStaticFiles plumbing (a StaticFiles implementation, not a
servlet) in a servlet-level mixin so any Juneau resource can opt into static-file serving via
@Rest(mixins=StaticFilesMixin.class). The mixin reads the active
StaticFiles from the bean store at request time — importer's
@Bean StaticFiles declarations + classpath defaults are picked up automatically.
Configurable mount path:
The default mount /static/* can be overridden via the SVL variable
${juneau.staticfiles.path:static} — set via system property
(-Djuneau.staticfiles.path=assets), environment variable
(JUNEAU_STATICFILES_PATH=assets), or Config key
(juneau.staticfiles.path = assets) to change the runtime mount without subclassing.
Resolution happens once at RestContext construction time (SVL resolution in @RestOp(path)).
Override accepts bare token (static), leading slash (/static), trailing slash
(static/), or wildcard suffix (/static/*) — all resolve to the same mount.
Migration note (10.0.0): Earlier development snapshots of this mixin mounted at both
/static/* and /htdocs/* as historical convenience aliases — that
dual default has been collapsed to a single SVL-configurable mount as part of the
"single path per op" principle. Deployers who relied on the /htdocs/*
alias must now either set -Djuneau.staticfiles.path=htdocs or compose a second
resource mounted with the htdocs override. The default StaticFiles classpath
search root still walks both static/ and htdocs/ directories — only the
URL-side mount is now single.
Mixin-only deployment:
This resource is designed for composition via @Rest(mixins=...). The mount path is
pinned at the op level by
@RestGet(path="/{juneau.staticfiles.path:static}/*") on getStaticFile(org.apache.juneau.rest.server.RestRequest, java.lang.String, java.util.Locale)
(and the matching RestOp for HEAD); a class-level @Rest(paths=...)
declaration would be silently ignored under the mixin pattern (see
@Rest(paths) Javadoc).
Composition example:
Behavior:
- GET hits the active
StaticFilesbean (resolved viaRestRequest.getStaticFiles()); missing paths surface asNotFoundthrown from the handler. HEADrequests are accepted via the standard servletHEAD-via-GETcontract: the response carries identical headers to the correspondingGET(includingCache-ControlandContent-Type) with an empty body.Cache-Controlheaders come from theBasicStaticFilesdefault (max-age=86400, public); importers can override viaBasicStaticFiles.create(beanStore).headers(...)when registering their own@Bean StaticFiles.- Default classpath base searches both
static/andhtdocs/directories on the importer's classpath (recursive walk viaBasicStaticFiles's built-inResourceSupplierhook).
Path matching:
The handler declares @RestGet(path="/${juneau.staticfiles.path:static}/*") so a single
Java method binds to the configured prefix (default /static/*). The trailing
/* captures the multi-segment remainder via @Path("/*") String path. Juneau's
UrlPathMatcher does not support the Spring/JAX-RS {var:regex} syntax —
each {var} matches a single segment only, and multi-segment matching is only available
via the trailing-* pattern shown here (same idiom as the legacy
BasicRestServlet.getHtdoc(...) accessor).
OpenAPI surface:
The greedy /* handler is not API-meaningful and is excluded from generated Swagger /
OpenAPI specs via @OpSwagger(ignore=true).
See Also:
BasicStaticFilesStaticFilesHtdocMixin— legacy fixed/htdocs/*mount; shares this mixin'sresolveStaticFile(org.apache.juneau.rest.server.RestRequest, java.lang.String, java.util.Locale)resolution logic- Static files
- REST Server — Mixins and Multi-Mount Paths
- Since:
- 10.0.0
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptiongetStaticFile(RestRequest req, String path, Locale locale) [GET /static/*] — serve a static file from the activeStaticFilesbean.headStaticFile(RestRequest req, String path, Locale locale) [HEAD /static/*] — return GET headers for a static file without the body.static HttpResourceresolveStaticFile(RestRequest req, String path, Locale locale) Shared static-file resolution chokepoint — resolves the requested path against the request's activeStaticFilesbean.
-
Constructor Details
-
StaticFilesMixin
public StaticFilesMixin()
-
-
Method Details
-
getStaticFile
[GET /static/*] — serve a static file from the activeStaticFilesbean.The
@Path("/*") String pathcaptures the multi-segment trailing remainder. TheLocaleparameter is auto-injected from the request and forwarded toStaticFiles.resolve(...)so localized lookups (e.g.styles_fr.css) work out of the box.- Parameters:
req- The current REST request — suppliesRestRequest.getStaticFiles().path- The trailing remainder after the mount prefix (the file path within thestatic/orhtdocs/classpath / filesystem search roots).locale- The request locale (used for localized resource lookups).- Returns:
- The matching
HttpResource(with content type + cache headers). - Throws:
NotFound- If no resource matches the requested path.
-
headStaticFile
[HEAD /static/*] — return GET headers for a static file without the body.Per RFC 7231 §4.3.2,
HEADmirrors the equivalentGET's headers (Content-Type, Content-Length, Cache-Control) but emits an empty response body. The sharedHttpResourceProcessorperforms the body suppression at the response-processor layer based onRestRequest.getMethod(), so this handler can delegate togetStaticFile(org.apache.juneau.rest.server.RestRequest, java.lang.String, java.util.Locale)verbatim.- Parameters:
req- The current REST request — suppliesRestRequest.getStaticFiles().path- The trailing remainder after the mount prefix.locale- The request locale (used for localized resource lookups).- Returns:
- The matching
HttpResource(with headers; body suppressed by the processor). - Throws:
NotFound- If no resource matches the requested path.
-
resolveStaticFile
public static HttpResource resolveStaticFile(RestRequest req, String path, Locale locale) throws NotFound Shared static-file resolution chokepoint — resolves the requested path against the request's activeStaticFilesbean.Used by both this mixin's
getStaticFile(org.apache.juneau.rest.server.RestRequest, java.lang.String, java.util.Locale)/headStaticFile(org.apache.juneau.rest.server.RestRequest, java.lang.String, java.util.Locale)handlers and byHtdocMixin's legacy/htdocs/*endpoint, so there is a single implementation of the resolution logic even though the two mixins expose different mounts.- Parameters:
req- The current REST request — suppliesRestRequest.getStaticFiles().path- The path to resolve (the trailing remainder after whichever mount prefix the caller uses).locale- The request locale (used for localized resource lookups).- Returns:
- The matching
HttpResource(with content type + cache headers). - Throws:
NotFound- If no resource matches the requested path.
-