In Config, we described how to associate a configuration file with your
microservice.
In this section we describe how that configuration can be used to customize the behavior or your REST resource
classes.
The most common usage for the configuration file is to reference values using the {@link oaj.config.vars.ConfigVar $C} variable in annotations.
For example, the {@link oajr.config.DefaultConfig} interface that defines the annotations that control the look-and-feel of
classes that extend from {@link oajr.servlet.BasicRestServlet} use several $C variables to externalize values:
| @Rest(
| ...
| // These are static files that are served up by the servlet under the specified sub-paths.
| // For example, "/servletPath/htdocs/javadoc.css" resolves to the file "[servlet-package]/htdocs/javadoc.css"
| // By default, we define static files through the external configuration file.
| staticFiles="$C{REST/staticFiles}"
| )
| // HTML-page specific settings
| @HtmlDocConfig(
|
| // Default page header contents.
| header={
| "<h1>$RS{title}</h1>", // Use @Rest(title)
| "<h2>$RS{operationSummary,description}</h2>", // Use either @RestOp(summary) or @Rest(description)
| "$C{REST/header}" // Extra header HTML defined in external config file.
| },
|
| // Default stylesheet to use for the page.
| // Can be overridden from external config file.
| // Default is DevOps look-and-feel (aka Depression look-and-feel).
| stylesheet="$C{REST/theme,servlet:/htdocs/themes/devops.css}",
|
| // Default contents to add to the <head> section of the HTML page.
| // Use it to add a favicon link to the page.
| head={
| "<link rel='icon' href='$U{$C{REST/favicon}}'/>"
| },
|
| // No default page footer contents.
| // Can be overridden from external config file.
| footer="$C{REST/footer}",
| ...
| )
| public interface BasicRestConfig {}
These values in turn are pulled from the external configuration file shown below.
Note that the configuration file can also contain $C variables.
| #=======================================================================================================================
| # REST settings
| #=======================================================================================================================
| [REST]
|
| # Mappings to folders containing static files.
| # Can be in the working directory or in the classpath.
| staticFiles = htdocs:files/htdocs
|
| # Stylesheet to use for HTML views.
| theme = servlet:/htdocs/themes/devops.css
|
| headerIcon = servlet:/htdocs/images/juneau.png
| headerLink = http://juneau.apache.org
| footerIcon = servlet:/htdocs/images/asf.png
| footerLink = http://www.apache.org
|
| favicon = $C{REST/headerIcon}
| header =
| <a href='$U{$C{REST/headerLink}}'>
| <img src='$U{$C{REST/headerIcon}}' style='position:absolute;top:5;right:5;background-color:transparent;height:30px'/>
| </a>
| footer =
| <a href='$U{$C{REST/footerLink}}'>
| <img src='$U{$C{REST/footerIcon}}' style='float:right;padding-right:20px;height:32px'/>
| </a>
Configuration files can also be accessed programmatically.
There are 3 primary ways of getting access to the config file:
- {@link oaj.microservice.Microservice#getConfig()}
Any initialization-time variables can be used.
- {@link oajr.RestContext#getConfig()}
Any initialization-time variables can be used.
| #----------------------------------
| # Configuration for MyHelloResource
| #----------------------------------
| [MyHelloResource]
| greeting = Hello world!
| #---------------------------------
| # Contents of MyHelloResource.java
| #---------------------------------
| @Rest(...)
| public class MyHelloResource extends BasicRestServlet {
| private String greeting;
|
| // Or access config file in servlet init method.
| @Override /* Servlet */
| public void init() {
| Config config = getContext().getConfig();
| this.greeting = config.getString("MyHelloResource/greeting");
| }
| }
Additional user-defined variables at the servlet level can be defined by adding a
{@link oajr.annotation.RestInit} hook method
and using the oajr.RestContext.Builder.vars(Class...) method.
-
{@link oajr.RestRequest#getConfig()}
- An instance method to access it from inside a REST method.
Any initialization-time or request-time variables can be used.
| #----------------------------------
| # Configuration for MyHelloResource
| #----------------------------------
| [MyHelloResource]
| greeting = Hello $RP{person}! // $RP is RequestPathVar
| localizedGreeting = $L{HelloMessage,$RP{person}} // $L is LocalizationVar with args
| #---------------------------------
| # Contents of MyHelloResource.java
| #---------------------------------
| @Rest(
| path="/hello",
| messages="nls/Messages",
| ...
| )
| public class MyHelloResource extends BasicRestServlet {
|
| /** Standard hello message. */
| @RestGet("/{person}")
| public String sayHello(RestRequest req) {
| return req.getConfig().getString("MyHelloResource/greeting");
| }
|
| /** Hello message in users language. */
| @RestGet("/localized/{person}")
| public String sayLocalizedHello(RestRequest req) {
| return req.getConfig().getString("MyHelloResource/localizedGreeting");
| }
| }
| #---------------------------------------
| # Contents of nls/Messages_en.properties
| #---------------------------------------
| MyHelloResource.HelloMessage = Hello {0}!
Additional user-defined variables can be defined at this level by overriding the
oajr.RestContext.Builder.vars(Class...) method.
That sayLocalizedHello() example might need some explanation since there's a lot going on there.
Here's what happens when an HTTP call is made to GET /hello/localized/Bob:
-
The HTTP call matches the /hello path on the MyHelloResource class.
-
The HTTP call matches the /localized/{person} path on the sayLocalizedHello() method.
-
The request attribute person gets assigned the value "Bob".
-
The call to req.getConfig().getString("MyHelloResource/localizedGreeting")
finds the value "$L{HelloMessage,$RP{person}}".
-
The arguments in the $L{} variable get resolved, resulting in "$L{HelloMessage,Bob}".
-
The $L{} variable gets resolved to the message "Hello {0}!" in the localized properties
file of the servlet based on the Accept-Language header on the request.
-
The arguments get replaced in the message resulting in "Hello Bob!".
-
The resulting message "Hello Bob!" is returned as a POJO to be serialized to whatever content
type was specified on the Accept header on the request.
This particular example is needlessly complex but it gives an idea of how variables can be used
recursively to produce sophisticated results