Handy URI Templates is a uritemplate processor implementing RFC6570 written in Java. If you are looking for a non-Java implementation, please check the RFC6570 implementations page. The current implementation is based on final realease of the uri template spec. The template processor supports the following features:
As of version 1.1.1, Handy URI Templates is passes all tests defined by the uritemplate-test suite.
URI Templates are useful if your building a client or server application that is a using a media type that leverages URI Templates. Some examples are:
URI Templates can even used by themselves as a convenient means of parameterizing URLs.
To use the library in your project, simply add the following to your projects pom:
<dependency> <groupId>com.damnhandy</groupId> <artifactId>handy-uri-templates</artifactId> <version>${version}</version> </dependency>
You can also download the artifact directly at http://search.maven.org
Using the library is simple:
String uri = UriTemplate.fromTemplate("/{foo:1}{/foo,thing*}{?query,test2}") .set("foo", "houses") .set("query", "Ask something") .set("test2", "something else") .set("thing", "A test") .expand();
This will result in the following URI:
"/h/houses/A%20test?query=Ask%20something&test2=someting%20else"
You can see more examples in some of the unit tests or you can read more in the JavaDocs.
The API can be used with existing HTTP frameworks like the most excellent Async Http Client. Using the GitHub API, we can use the a UriTemplate to create a URI to look at this repository:
RequestBuilder builder = new RequestBuilder("GET"); Request request = builder.setUrl( UriTemplate.fromTemplate("https://api.github.com/repos{/user,repo,function,id}") .set("user", "damnhandy") .set("repo", "Handy-URI-Templates") .set("function","commits") .expand()).build();
When Request.getUrl() is called, it will return:
"https://api.github.com/repos/damnhandy/Handy-URI-Templates/commits"
Please have a look at the example test case for more details.
Usage with the Apache HTTP Client is just as similar.
While the set() method of the UriTemplate accepts any Java object, the following Java types are preferred:
Values that are not strings are rendered into the URI by calling its toString() method. Java objects can be treated as composite objects (as name/value pairs) when the variable specifies the explode modifier (see Composite Value below). A char[] or Character[] array will be treated as String. A multi dimensional character array will be treated as a List of Strings.
The template processor will not accept the following types of value combinations:
If you need such data structures in a URI, consider implementing your own VarExploder to handle it.
The URI Template spec supports composite values where the variable may be a list of values of an associative array of (name, value) pairs. The template processor always treats lists as java.util.List and name/value pairs as a java.util.Map. Lists and Maps work with any supported type that is not anoth List, Map, or array.
The template process can treat simple Java objects as composite value. When a POJO is set on a template variable and the variable specifies the an explode modifier “*”, a VarExploder is invoked. The purpose of the VarExploder is to expose the object properties as name/value pairs.
For most use cases, the DefaultVarExploder should be sufficient. The DefaultVarExploder is a VarExploder implementation that takes in a Java object and extracts the properties for use in a URI Template. This class is called by default when a POJO is passed into the UriTemplate and the explode modifier is present on the variable. Given the following URI template expression:
/mapper{?address*}
And this Java object for an address:
Address address = new Address(); address.setState("CA"); address.setCity("Newport Beach"); String result = UriTemplate.fromTemplate("/mapper{?address*}") .set("address", address) .expand();
The expanded URI will be:
/mapper?city=Newport%20Beach&state=CA
The DefaultVarExploder breaks down the object properties as follows:
Please refer to the JavaDoc for more details on how the DefaultVarExploder works.
Should the DefaultVarExploder not be suitable for your needs, custom VarExploder implementations can be added by rolling your own implementation. A custom VarExploder implementation can be used by wrapping your object in your implementation:
UriTemplate.fromTemplate("/mapper{?address*}") .set("address", new MyCustomVarExploder(address)) .expand();
Note: All VarExploder implementations are ONLY invoked when the explode modifier “*” is declared in the URI Template expression. If the variable declaration does not specify the explode modifier, an exception is raised.
Copyright 2011-2016 Ryan J. McDonough
Licensed 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.