{title:'Config', created:'8.0.0'}

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:

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:

  1. The HTTP call matches the /hello path on the MyHelloResource class.
  2. The HTTP call matches the /localized/{person} path on the sayLocalizedHello() method.
  3. The request attribute person gets assigned the value "Bob".
  4. The call to req.getConfig().getString("MyHelloResource/localizedGreeting") finds the value "$L{HelloMessage,$RP{person}}".
  5. The arguments in the $L{} variable get resolved, resulting in "$L{HelloMessage,Bob}".
  6. 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.
  7. The arguments get replaced in the message resulting in "Hello Bob!".
  8. 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