public class ServerPagesBundle
extends java.lang.Object
implements io.dropwizard.ConfiguredBundle<io.dropwizard.Configuration>
First of all global server pages support bundle must be installed (builder(), preferably directly in the
application class). This will activates dropwizard-views support (ViewBundle). Do not register
ViewBundle it manually!
Each server pages application is also registered
as separate bundle (using app(String, String, String) or adminApp(String, String, String)).
Views configuration could be mapped from yaml file in main bundle:
ServerPagesBundle.ViewsBuilder.viewsConfiguration(ViewConfigurable). In order to fine tune configuration use
ServerPagesBundle.AppBuilder.viewsConfigurationModifier(String, ViewRendererConfigurationModifier) which could be used by
applications directly in order to apply required defaults. But pay attention that multiple apps could collide in
configuration (configure the same property)! Do manual properties merge instead of direct value set where possible
to maintain applications compatibility (e.g. you declare admin dashboard and main users app, which both use
freemarker and require default templates).
Renderers (pluggable template engines support) are loaded with service lookup mechanism (default for
dropwizard-views) but additional renderers could be registered with
ServerPagesBundle.ViewsBuilder.addViewRenderers(ViewRenderer...). Most likely, server page apps will be bundled as 3rd party
bundles and so they can't be sure what template engines are installed in target application. Use
ServerPagesBundle.AppBuilder.requireRenderers(String...) to declare required template engines for each application and
fail fast if no required templates engine. Without required engines declaration template files will be served like
static files when direct template requested and rendering will fail for rest-mapped template.
Pay attention that application bundles are dropwizard bundles (not guicey bundles) so register it directly in
bootstrap object. This is required to be able to register multiple server applications. It could be also be
registered within GuiceyBundle using builder register
method (ServerPagesBundle.AppBuilder.register(GuiceyBootstrap)).
Each application could be "extended" using extendApp(String, String). This way extra
classpath location is mapped into application root. Pages from extended context could reference resources from
the main context (most likely common root template will be used). Also, extended mapping could override
resources from the primary location (but note that in case of multiple extensions order is not granted).
Obvious case for extensions feature is dashboards, when extensions add extra pages to common dashboard
application, but all new pages still use common master template.
Application work scheme: assets servlet is registered on the configured path in order to serve static assets
(customized version of dropwizard AssetServlet used which could
recognize both primary and extended locations). Special filter above servlet detects file calls (by extension,
but checks if requested file is template (and that's why list of supported templates is required)). If request
is not for file, it's redirected to rest endpoint in order to render view (note that direct template files will
also be rendered). Redirection scheme use application name, defined during bundle creation:
{rest prefix}/{app name}/{path from request}.
For example,
bootstrap.addBundle(SpaPageBundle.app("ui", "/com/assets/path/", "ui/").build())
Register application in main context, mapped to "ui/" path, with static resources in "/com/assets/path/"
classpath path. Internal application name is "ui". When browser request any file directly, e.g.
"ui/styles.css" then file "/com/assets/path/styles.css" will be served. Any other path is redirected to rest
endpoint: e.g. "ui/dashboard/" is redirected to "{rest mapping}/ui/dashboard.
@Template("dashboard.ftl")
@Path("ui/dahboard")
@Produces(MediaType.TEXT_HTML)
public class DashboardPage {
@GET
public DashboardView get() {
return new DashboardView();
}
}
Note that Template annotation on resource is required. Without it,
bundle will not be able to show path in console reporting. Also, configured template automatically applied
into view (so you don't have to specify template path in all methods (note that custom template path could
still be specified directly, when required). View class must extend
TemplateView. In all other aspects, it's pure dropwizard views.
Template annotation is jersey NameBinding marker
so you can apply request/response filters only (!) for template resources (see TemplateAnnotationFilter
as example).
Note that all resources, started from application name prefix are considered to be used in application.
extendApp(String, String) mechanism is used only to declare additional static resources
(or direct templates). But in order to add new pages, handled by rest resources you dont need to do anything -
they just must start with correct prefix (you can see all application resources in console just after startup).
In order to be able to render direct templates (without supporting rest endpoint) special rest endpoint is registered which handles everything on application path (e.g. "ui/{file:.*}" for example application above). Only POST and GET supported for direct templates.
Bundle unifies custom pages handling to be able to use default 404 or 500 pages (for both assets and resources).
Use builder ServerPagesBundle.AppBuilder.errorPage(int, String) method to map template (or pure html)
to response code (to be shown instead).
Bundle could also enable filter from SpaBundle in order to support single
page applications routing (for cases when root page must be template and not just html, which makes direct usage of
SpaBundle useless).
| Modifier and Type | Class and Description |
|---|---|
static class |
ServerPagesBundle.AppBuilder
Server pages application bundle builder.
|
static class |
ServerPagesBundle.ViewsBuilder
Global server pages support bundle builder.
|
| Modifier and Type | Field and Description |
|---|---|
static java.lang.String |
FILE_REQUEST_PATTERN
Default pattern for file request detection.
|
| Constructor and Description |
|---|
ServerPagesBundle(GlobalConfig config) |
| Modifier and Type | Method and Description |
|---|---|
static ServerPagesBundle.AppBuilder |
adminApp(java.lang.String name,
java.lang.String resourcePath,
java.lang.String uriPath)
Register application in admin context.
|
static ServerPagesBundle.AppBuilder |
app(java.lang.String name,
java.lang.String resourcePath,
java.lang.String uriPath)
Register application in main context.
|
static ServerPagesBundle.ViewsBuilder |
builder()
Creates global server pages support bundle which must be registered in the application.
|
static void |
extendApp(java.lang.String name,
java.lang.String resourcePath)
Extend application resources (classpath) with new location.
|
java.util.List<io.dropwizard.views.ViewRenderer> |
getRenderers()
Method is available for custom template detection logic (similar that used inside server pages filter)
or to validate state in tests.
|
java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.String>> |
getViewsConfig()
Method is available for custom views configuration state analysis logic (after startup) or to validate
state in tests.
|
void |
initialize(io.dropwizard.setup.Bootstrap<?> bootstrap) |
static void |
resetGlobalConfig()
Remove current global configuration.
|
void |
run(io.dropwizard.Configuration configuration,
io.dropwizard.setup.Environment environment) |
public static final java.lang.String FILE_REQUEST_PATTERN
public ServerPagesBundle(GlobalConfig config)
public static ServerPagesBundle.ViewsBuilder builder()
ViewBundle). If views bundle is manually declared in
application, it must be removed (to avoid duplicates). View bundle owning is required for proper configuration
and to know all used template engines (renderers).
After global support is registered, server pages applications may be declared with
app(String, String, String) and adminApp(String, String, String).
It is assumed that global bundles support is registered directly in the dropwizard application (and not transitively in some bundle) and server page applications themselves could be registered nearby (in dropwizard application) or in any bundle (for example, some dashboard bundle just registers dashboard application, assuming that global server pages support would be activated).
public static ServerPagesBundle.AppBuilder app(java.lang.String name, java.lang.String resourcePath, java.lang.String uriPath)
Application could be extended with extendApp(String, String) in another
bundle.
NOTE global server pages support bundle must be installed with builder() in dropwizard application.
name - application name (used as servlet name)resourcePath - path to application resources (classpath)uriPath - mapping urifor server pages applications global supportpublic static ServerPagesBundle.AppBuilder adminApp(java.lang.String name, java.lang.String resourcePath, java.lang.String uriPath)
You can't register admin application on admin context root because there is already dropwizard
admin servlet AdminServlet.
Application could be extended with extendApp(String, String) in another
bundle.
NOTE: global server pages support bundle must be installed with builder() in dropwizard application.
name - application name (used as servlet name)resourcePath - path to application resources (classpath)uriPath - mapping urifor server pages applications global supportpublic static void extendApp(java.lang.String name,
java.lang.String resourcePath)
ServerPagesBundle.app("ui", "/com/path/assets/", "/ui") it will server static resources only from
"/com/path/assets/" package. Suppose we want to add another page (with direct template) into the app:
ServerPagesBundle.extendApp("ui", "/com/another/assets/"). Now assets will be searched in both packages
and if we have "/com/another/assets/page.tpl" then calling url "/ui/page.tpl" will render template.
Resource in extended location could override original app resource: e.g. if we have
"/com/another/assets/style.css" (extended) and "/com/path/assets/style.css" (original app) then
"/ui/style.css" will return extended resource file.
Note that if you just want to add new rest resources then simply prefix resource paths with application name and they will be included automatically (in example above app name is "ui" and note that name is completely internal and may not be the same as path mapping ("/ui" in example above).
If extended application is not registered no error will be thrown. This behaviour support optional application extension support (extension will work if extended application registered and will not harm if not).
name - extended application nameresourcePath - classpath location for additional resourcesjava.lang.IllegalStateException - if target application is already initializedpublic static void resetGlobalConfig()
WARNING: intended to be used by internal tests only (because global context listens for app shutdowns and so not cause problems neither in usual run nor in tests).
public java.util.List<io.dropwizard.views.ViewRenderer> getRenderers()
public java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.String>> getViewsConfig()
java.lang.NullPointerException - if views configuration is not yet created (views ot initialized)public void initialize(io.dropwizard.setup.Bootstrap<?> bootstrap)
initialize in interface io.dropwizard.ConfiguredBundle<io.dropwizard.Configuration>public void run(io.dropwizard.Configuration configuration,
io.dropwizard.setup.Environment environment)
throws java.lang.Exception
run in interface io.dropwizard.ConfiguredBundle<io.dropwizard.Configuration>java.lang.Exception