Introduction
Unaltered Turbine URLs may look like this:
http://www.foo.com:8080/CONTEXT/servlet/MAPPING/template/Foo.vm
.
But you want shorter URLs? Maybe this URL would suit you better:
http://www.foo.com:8080/CONTEXT/servlet/beautiful/world
Turbine URLMapper Configuration
You need to
- register the URL Mapper service in turbine configuration (TR.properties)
- register the valve in the pipeline (turbine-classic-pipeline.xml)
Consider the following example configuration: MappedTemplateLink is for now optional, you can add it as a separate tool or just replace the existing TemplateLink.
# ------------------------------------------------------------------- # # U R L M A P P E R S E R V I C E # # ------------------------------------------------------------------- # required services.URLMapperService.classname=org.apache.turbine.services.urlmapper.TurbineURLMapperService # configFile is required here! xml, json and yml supported as extension. services.URLMapperService.configFile = /conf/turbine-url-mapping.xml # new mapper (optional) tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink # tool.request.jlink= org.apache.turbine.services.pull.tools.TemplateLink
To resolve a provided / mapped URL add the valve into pipeline (pipeline.default.descriptor = /conf/turbine-classic-pipeline.xml).
<valves> <valve>org.apache.turbine.services.urlmapper.URLMapperValve</valve> ...
This will check if the provided URL matches any pattern, resolves it given in the path or implicitly as defined in the URLMapperService's configfile.
Define your patterns
The URL Mapping Mechanism uses a well defined pattern format. The pattern format scheme is defined as follows, e.g. in JSON:
"pattern": "/(?<webAppRoot>[.\\-\\w]+)/(?<contextPath>\\w+)/(?<resolvableParam>\\w+)/beautifulname"
That is resolvableParam is just a specific parameter name or key, which should be resolved after the context slash and before the next URL part, which starts with "/beatifulname". It has to be set like this
/(?<resolvableParam>\\w+)
Another condition to be met, is that the parameter name must follow the "Java Named Group pattern characters restriction":
NAMED_GROUPS_PATTERN = Pattern.compile("(?<([a-zA-Z][a-zA-Z0-9]*)>.+?)");
Any parameter is resolved as a group name (Java Pattern->Groups and Capturing->Group name). These group names are predefined (symbolic group name)):
- <webAppRoot>
- <contextPath>
<url-mapping name="default"> <maps> <map> <pattern>/(?<webAppRoot>[.\\-\\w]+)/(?<contextPath>\w+)/book/(?<bookId>\d+)</pattern> <implicit-parameters> <parameter key="template">Book.vm</parameter> <parameter key="detail">0</parameter> </implicit-parameters> </map> ...
Three parameters are evaluated:
- a parameter name template and value Book.vm
- a parameter detail and value 0
- a parameter bookId with any value, e.g. 4
Another example in JSON format, which is much more readable, if not viewing in a browser is here (showing a shortened URL by replacing two parameters):
{ "name": "default", "maps": [ { "pattern": "/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/register", "implicit-parameters": { "page": "Register", "role": "anon" } }, ...
Service Description
The main methods of the service TurbineURLMapperService are
- mapToUrl, which as the Javadoc explains "maps a set of parameters (contained in TurbineURI PathInfo and QueryData) to a TurbineURIs"
- mapFromUrl, which "maps a simplified URL to a set of parameters"
Matrix
Turbine URL Mapper Model | |||||
---|---|---|---|---|---|
Mechanism | Method | Pattern | Implicit Param | Override Param | Ignore Param |
Converts Parameterized URL to simplified URL | mapToUrl | "Match Group Name": The pattern of the target URL after evaluation of parameters. If a group name is set, a matching parameter key must be provided and the value will replace the group name in the target URL. | "Exact Filter", "Reduce": If a parameter key is is set implicitely, both key and value must exactly matched by a parameter pair in the provided (unmapped) URI. It will then be removed | - An override could be achieved by hard coding it in the pattern and filterign in implicit param. On the other hand you can then ignore the parameter | The parameter will be removed from the required parameter key set and also from the target URL if it is provided as a group name |
Resolves URL to Params for evaluating by the backend | mapFromUrl | The pattern of the URL to be matched to evaluate parameter resolving | Param key/value will be set implicitely | Overrides (provided) URL parameter with provided value | will remove parameter key/value from result parameter list, even if provided as capturing group name |
N.B. Symbolic group names webAppRoot and context could not be ignored or overridden!
Usage
Use the methods getRelative or getAbsoluteLink of the provided convenience class MappedTemplateLink class (of type TemplateLink) in a velocity template like this:
$mlink.addPathInfo("world","nice").getRelativeLink() ## should result into a URL: /beautiful/world
Alternatively you can use the service explicitely in Java, e.g. in a Java Action or other class if you inject the URLMapperService (or provide this in a shared controller class).
// inside any assembler you may alternatively use annotation // @TurbineService( "URLMapperService" ) urlMapper; URLMapperService urlMapper = (URLMapperService) TurbineServices.getInstance().getService(URLMapperService.SERVICE_NAME); // Any turbineURI ..e.g. from PoolService or TurbineURI uri ... urlMapper.mapToURL( uri ); // use it, e.g by putting it into a velocity context (org.apache.velocity.context.Context( context.put("myLink", link);