| <!-- |
| /*************************************************************************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations under the License. |
| ***************************************************************************************************************************/ |
| --> |
| |
| Config |
| |
| <p> |
| In {@doc juneau-microservice-core.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. |
| </p> |
| <p> |
| 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.BasicRestConfig} interface that defines the annotations that control the look-and-feel of |
| classes that extend from {@link oajr.BasicRestServlet} use several <c>$C</c> variables to externalize values: |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Rest</ja>( |
| ... |
| |
| <jc>// HTML-page specific settings</jc> |
| htmldoc=<ja>@HtmlDoc</ja>( |
| |
| <jc>// Default page header contents.</jc> |
| header={ |
| <js>"<h1>$R{resourceTitle}</h1>"</js>, <jc>// Use @Rest(title)</jc> |
| <js>"<h2>$R{methodSummary,resourceDescription}</h2>"</js>, <jc>// Use either @RestMethod(summary) or @Rest(description)</jc> |
| <js>"$C{REST/header}"</js> <jc>// Extra header HTML defined in external config file.</jc> |
| }, |
| |
| <jc>// 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).</jc> |
| stylesheet=<js>"$C{REST/theme,servlet:/htdocs/themes/devops.css}"</js>, |
| |
| <jc>// Default contents to add to the <head> section of the HTML page. |
| // Use it to add a favicon link to the page.</jc> |
| head={ |
| <js>"<link rel='icon' href='$U{$C{REST/favicon}}'/>"</js> |
| }, |
| |
| <jc>// No default page footer contents. |
| // Can be overridden from external config file.</jc> |
| footer=<js>"$C{REST/footer}"</js>, |
| ... |
| ), |
| |
| <jc>// 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.</jc> |
| staticFiles=<js>"$C{REST/staticFiles}"</js> |
| ) |
| <jk>public interface</jk> BasicRestConfig {} |
| </p> |
| <p> |
| These values in turn are pulled from the external configuration file shown below. |
| Note that the configuration file can also contain <c>$C</c> variables. |
| </p> |
| <p class='bpcode w800'> |
| <cc>#======================================================================================================================= |
| # REST settings |
| #=======================================================================================================================</cc> |
| <cs>[REST]</cs> |
| |
| <cc># Mappings to folders containing static files.</cc> |
| <cc># Can be in the working directory or in the classpath.</cc> |
| <ck>staticFiles</ck> = <cv>htdocs:files/htdocs</cv> |
| |
| <cc># Stylesheet to use for HTML views.</cc> |
| <ck>theme</ck> = <cv>servlet:/htdocs/themes/devops.css</cv> |
| |
| <ck>headerIcon</ck> = <cv>servlet:/htdocs/images/juneau.png</cv> |
| <ck>headerLink</ck> = <cv>http://juneau.apache.org</cv> |
| <ck>footerIcon</ck> = <cv>servlet:/htdocs/images/asf.png</cv> |
| <ck>footerLink</ck> = <cv>http://www.apache.org</cv> |
| |
| <ck>favicon</ck> = <cv>$C{REST/headerIcon}</cv> |
| <ck>header</ck> = |
| <cv><a href='$U{$C{REST/headerLink}}'></cv> |
| <cv><img src='$U{$C{REST/headerIcon}}' style='position:absolute;top:5;right:5;background-color:transparent;height:30px'/></cv> |
| <cv></a></cv> |
| <ck>footer</ck> = |
| <cv><a href='$U{$C{REST/footerLink}}'></cv> |
| <cv><img src='$U{$C{REST/footerIcon}}' style='float:right;padding-right:20px;height:32px'/></cv> |
| <cv></a></cv> |
| </p> |
| |
| <p> |
| Configuration files can also be accessed programmatically. |
| There are 3 primary ways of getting access to the config file: |
| </p> |
| <ul class='javatree'> |
| <li class='jm'>{@link oaj.microservice.Microservice#getConfig()} |
| <p>Any {@doc DefaultRestSvlVariables initialization-time variables} can be used.</p> |
| <li class='jm'>{@link oajr.RestContext#getConfig()} |
| <p>Any {@doc DefaultRestSvlVariables initialization-time variables} can be used.</p> |
| <h5 class='figure'>Example usage:</h5> |
| <p class='bcode w800'> |
| <cc>#----------------------------------</cc> |
| <cc># Configuration for MyHelloResource </cc> |
| <cc>#----------------------------------</cc> |
| <cs>[MyHelloResource]</cs> |
| <ck>greeting</ck> = <cv>Hello world!</cv> |
| </p> |
| <p class='bcode w800'> |
| <cc>#---------------------------------</cc> |
| <cc># Contents of MyHelloResource.java </cc> |
| <cc>#---------------------------------</cc> |
| <ja>@Rest</ja>(...) |
| <jk>public class</jk> MyHelloResource <jk>extends</jk> BasicRestServlet { |
| <jk>private</jk> String <jf>greeting</jf>; |
| |
| <jc>// Or access config file in servlet init method.</jc> |
| <ja>@Override</ja> <jc>/* Servlet */</jc> |
| <jk>public void</jk> init() { |
| Config c = getContext().getConfig(); |
| <jk>this</jk>.<jf>greeting</jf> = c.getString(<js>"MyHelloResource/greeting"</js>); |
| } |
| } |
| </p> |
| <p> |
| Additional user-defined variables at the servlet level can be defined by adding a |
| {@link oajr.annotation.HookEvent#INIT} hook method |
| and using the {@link oajr.RestContextBuilder#vars(Class...)} method. |
| </p> |
| <li class='jm'> |
| {@link oajr.RestRequest#getConfig()} |
| - An instance method to access it from inside a REST method. |
| <p>Any {@doc DefaultRestSvlVariables initialization-time or request-time variables} can be used.</p> |
| |
| <h5 class='figure'>Example usage:</h5> |
| <p class='bcode w800'> |
| <cc>#----------------------------------</cc> |
| <cc># Configuration for MyHelloResource</cc> |
| <cc>#----------------------------------</cc> |
| <cs>[MyHelloResource]</cs> |
| <ck>greeting</ck> = <cv>Hello $RP{person}!</cv> <cc>// $RP is RequestPathVar</cc> |
| <ck>localizedGreeting</ck> = <cv>$L{HelloMessage,$RP{person}}</cv> <cc>// $L is LocalizationVar with args</cc> |
| </p> |
| <p class='bcode w800'> |
| <cc>#---------------------------------</cc> |
| <cc># Contents of MyHelloResource.java </cc> |
| <cc>#---------------------------------</cc> |
| <ja>@Rest</ja>( |
| path=<js>"/hello"</js>, |
| messages=<js>"nls/Messages"</js>, |
| ... |
| ) |
| <jk>public class</jk> MyHelloResource <jk>extends</jk> BasicRestServlet { |
| |
| <jd>/** Standard hello message. */</jd> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/{person}"</js>) |
| <jk>public</jk> String sayHello(RestRequest req) { |
| <jk>return</jk> req.getConfig().getString(<js>"MyHelloResource/greeting"</js>); |
| } |
| |
| <jd>/** Hello message in users language. */</jd> |
| <ja>@RestMethod</ja>(name=<jsf>GET</jsf>, path=<js>"/localized/{person}"</js>) |
| <jk>public</jk> String sayLocalizedHello(RestRequest req) { |
| <jk>return</jk> req.getConfig().getString(<js>"MyHelloResource/localizedGreeting"</js>); |
| } |
| } |
| </p> |
| <p class='bcode w800'> |
| <cc>#---------------------------------------</cc> |
| <cc># Contents of nls/Messages_en.properties </cc> |
| <cc>#---------------------------------------</cc> |
| <ck>MyHelloResource.HelloMessage</ck> = <cv>Hello {0}!</cv> |
| </p> |
| <p> |
| Additional user-defined variables can be defined at this level by overriding the |
| {@link oajr.RestContextBuilder#vars(Class...)} method. |
| </p> |
| </ul> |
| <p> |
| That <l>sayLocalizedHello()</l> example might need some explanation since there's a lot going on there. |
| Here's what happens when an HTTP call is made to <l>GET /hello/localized/Bob</l>: |
| </p> |
| <ol class='spaced-list'> |
| <li> |
| The HTTP call matches the <l>/hello</l> path on the <l>MyHelloResource</l> class. |
| <li> |
| The HTTP call matches the <l>/localized/{person}</l> path on the <l>sayLocalizedHello()</l> method. |
| <li> |
| The request attribute <l>person</l> gets assigned the value <l>"Bob"</l>. |
| <li> |
| The call to <l>req.getConfig().getString("MyHelloResource/localizedGreeting")</l> |
| finds the value <l>"$L{HelloMessage,$RP{person}}"</l>. |
| <li> |
| The arguments in the <l>$L{}</l> variable get resolved, resulting in <l>"$L{HelloMessage,Bob}"</l>. |
| <li> |
| The <l>$L{}</l> variable gets resolved to the message <l>"Hello {0}!"</l> in the localized properties |
| file of the servlet based on the <l>Accept-Language</l> header on the request. |
| <li> |
| The arguments get replaced in the message resulting in <l>"Hello Bob!"</l>. |
| <li> |
| The resulting message <l>"Hello Bob!"</l> is returned as a POJO to be serialized to whatever content |
| type was specified on the <l>Accept</l> header on the request. |
| </ol> |
| <p> |
| This particular example is needlessly complex, but it gives an idea of how variables can be used |
| recursively to produce sophisticated results |
| </p> |
| |
| <ul class='seealso'> |
| <li class='link'>{@doc juneau-config} |
| </ul> |
| |