Class ServerPagesBundle
- All Implemented Interfaces:
ru.vyarus.dropwizard.guice.module.installer.bundle.GuiceyBundle
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 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
ServerPagesAppBundle.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
ServerPagesAppBundle.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.
Each application could be "extended" using extendApp(String) bundle. 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,
.bundles(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) 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 ServerPagesAppBundle.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).
Information about configured application may be acquired through GspInfoService
guice bean. But it could be used only after complete gsp initialization (between dropwizard run and jersey start).
- Since:
- 22.10.2018
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classGlobal server pages support bundle builder. -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionRegister application in admin context.adminApp(String name, String assetsPath, String uriPath, ClassLoader loader) Same asadminApp(String, String, String)but with custom classloader to use for assets loading.Register application in main context.app(String name, String assetsPath, String uriPath, ClassLoader loader) Same asapp(String, String, String)but with custom classloader to use for assets loading.builder()Creates global server pages support bundle which must be registered in the application.Extend registered application.extendApp(String name, ClassLoader loader) Same asextendApp(String)but with custom classloader to use for assets loading.List<io.dropwizard.views.common.ViewRenderer>Method is available for custom template detection logic (similar that used inside server pages filter) or to validate state in tests.Method is available for custom views configuration state analysis logic (after startup) or to validate state in tests.voidinitialize(ru.vyarus.dropwizard.guice.module.installer.bundle.GuiceyBootstrap bootstrap) voidrun(ru.vyarus.dropwizard.guice.module.installer.bundle.GuiceyEnvironment environment) Methods inherited from class ru.vyarus.dropwizard.guice.module.context.unique.item.UniqueGuiceyBundle
equals, hashCode
-
Field Details
-
FILE_REQUEST_PATTERN
Default pattern for file request detection.
-
-
Constructor Details
-
ServerPagesBundle
-
-
Method Details
-
builder
Creates global server pages support bundle which must be registered in the application. Bundle installs standard dropwizard views bundle (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)andadminApp(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).
- Returns:
- global views bundle builder
-
app
Register application in main context. Application names must be unique (when you register multiple server pages applications).Application could be extended with
extendApp(String)in another bundle.NOTE global server pages support bundle must be installed with
builder()in dropwizard application.- Parameters:
name- application name (used as servlet name)assetsPath- path to application resources (classpath); may be in form of package (dot-separated)uriPath- mapping uri- Returns:
- builder instance for server pages application configuration
- See Also:
-
app
public static ServerPagesAppBundle.AppBuilder app(String name, String assetsPath, String uriPath, ClassLoader loader) Same asapp(String, String, String)but with custom classloader to use for assets loading. All additional registration through this builder (ServerPagesAppBundle.AppBuilder.attachAssets(String)) would also be registered with provided class loader.WARNING: custom class loader will be automatically supported for static resources, but template engine may not be able to resolve template. For example, freemarker use class loader of resource class serving view, so if resource class and view template are in the same class loader then it will work. For sure direct template rendering (without custom resource class) will not work. Freemarker may be configured to support all cases with custom template loader (see
ServerPagesBundle.ViewsBuilder.enableFreemarkerCustomClassLoadersSupport()) which must be configured manually. Mustache is impossible to configure properly (with current mustache views renderer).- Parameters:
name- application name (used as servlet name)assetsPath- path to application resources (classpath); may be in form of package (dot-separated)uriPath- mapping uriloader- class loader to use for assets loading- Returns:
- builder instance for server pages application configuration
- See Also:
-
adminApp
public static ServerPagesAppBundle.AppBuilder adminApp(String name, String assetsPath, String uriPath) Register application in admin context. Application names must be unique (when you register multiple server pages applications).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)in another bundle.NOTE: global server pages support bundle must be installed with
builder()in dropwizard application.- Parameters:
name- application name (used as servlet name)assetsPath- path to application resources (classpath)uriPath- mapping uri- Returns:
- builder instance for server pages application configuration
- See Also:
-
adminApp
public static ServerPagesAppBundle.AppBuilder adminApp(String name, String assetsPath, String uriPath, ClassLoader loader) Same asadminApp(String, String, String)but with custom classloader to use for assets loading. All additional registration through this builder (ServerPagesAppBundle.AppBuilder.attachAssets(String)) would also be registered with provided class loader.WARNING: custom class loader will be automatically supported for static resources, but template engine may not be able to resolve template. For example, freemarker use class loader of resource class serving view, so if resource class and view template are in the same class loader then it will work. For sure direct template rendering (without custom resource class) will not work. Freemarker may be configured to support all cases with custom template loader (see
ServerPagesBundle.ViewsBuilder.enableFreemarkerCustomClassLoadersSupport()) which must be configured manually. Mustache is impossible to configure properly (with current mustache views renderer).- Parameters:
name- application name (used as servlet name)assetsPath- path to application resources (classpath)uriPath- mapping uriloader- class loader to use for assets loading- Returns:
- builder instance for server pages application configuration
- See Also:
-
extendApp
Extend registered application. The most common use case is adding or overriding static assets of target application (e.g. for visual customization). Extension may be called before or after application registration - it does not matter.For example, if we register application like this
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").attachAssets("/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.For new views addition, you may simply register new rest resources with prefix, used by application and it will detect it automatically (in example above app name is "ui").
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).
Unlimited number of extensions could be registered for the same application (all extensions will be applied).
- Parameters:
name- extended application name- Returns:
- application extension bundle
-
extendApp
public static ServerPagesAppExtensionBundle.AppExtensionBuilder extendApp(String name, ClassLoader loader) Same asextendApp(String)but with custom classloader to use for assets loading. All additional registration through this builder (ServerPagesAppBundle.AppBuilder.attachAssets(String)) would also be registered with provided class loader.WARNING: custom class loader will be automatically supported for static resources, but template engine may not be able to resolve template. For example, freemarker use class loader of resource class serving view, so if resource class and view template are in the same class loader then it will work. For sure direct template rendering (without custom resource class) will not work. Freemarker may be configured to support all cases with custom template loader (see
ServerPagesBundle.ViewsBuilder.enableFreemarkerCustomClassLoadersSupport()) which must be configured manually. Mustache is impossible to configure properly (with current mustache views renderer).- Parameters:
name- extended application nameloader- class loader to use for assets loading- Returns:
- application extension bundle
-
getRenderers
Method is available for custom template detection logic (similar that used inside server pages filter) or to validate state in tests.- Returns:
- list of used renderers (supported template engines)
-
getViewsConfig
Method is available for custom views configuration state analysis logic (after startup) or to validate state in tests.- Returns:
- final views configuration object (unmodifiable)
- Throws:
NullPointerException- if views configuration is not yet created (views ot initialized)
-
initialize
public void initialize(ru.vyarus.dropwizard.guice.module.installer.bundle.GuiceyBootstrap bootstrap) -
run
public void run(ru.vyarus.dropwizard.guice.module.installer.bundle.GuiceyEnvironment environment)
-