A Java tool for generating json strings.
<dependency>
<groupId>com.github.json-template</groupId>
<artifactId>jsontemplate</artifactId>
<version>0.2.1</version>
</dependency>
Suppose that we want to create the following json String,
{
"name" : "John",
"age" : 23,
"role" : [ "developer", "tester" ],
"address" : {
"city" : "Utrecht",
"street" : "Musicallaan",
"number" : 413
}
}
With JsonTemplate, you can do it in the following way. Compared to the typical solution, JsonTemplate saves you effort in reading and writing the escaped quotes "\"".
String template = "{" +
" name : John," +
" age : 23," +
" role : [ developer, tester ]," +
" address : {" +
" city : Utrecht," +
" street : Musicallaan," +
" number : 413" +
" }" +
"}";
String json = new JsonTemplate(template).prettyString();
Furthermore, suppose that what you need is only a schema-compatible json and you don't want to bother with the specific values. This is usually the case when you test the validation logic in the controllers. JsonTemplate allows you to code in the following way:
String template = "{" +
" name : @s," +
" age : @i(max=100)," +
" role : @s[](min=1, max=3)," +
" address : {" +
" city : @s," +
" street : @s," +
" number : @i" +
" }" +
"}";
String json = new JsonTemplate(template).prettyString();
Template | Generated Json |
---|---|
{ name : John, age : 23, accountBalance: 30.4, married : true, role : programmer } | { "name" : "John", "age" : 23, "accountBalance": 30.4, "married" : true, "role" : "programmer" } |
If this is not the intention, a specific value producer needs to be given, e.g. @s(23)
.
Template | Generated Json |
---|---|
{ aField : @s } | { "aField" : "ISCZd" } |
In JsonTemplate, @x can refer to a value producer or a value producer declaration (will be described later). When it is at the value part, it is a value producer.
Following is the table about all the pre-installed value producers:
value producer | description |
---|---|
@smart | used for smart conversion, it is the default value producer which is implicitly used. |
@s | produces a string |
@i | produces an integer |
@f | produces a float |
@b | produces a boolean |
@raw | produces a raw string content |
@ip | produces an ip string |
@ipv6 | produces an ipv6 string |
@base64 | produces a base64 string |
@iso8601 | produces a ISO8601 string |
@cat | used for concatenating strings |
Template | Generated Json |
---|---|
{ aField : @s(myValue) } | { "aField" : "myValue" } |
If a single parameter is given, the value producer produces a fixed value correspondingly by default.
Template | Generated Json |
---|---|
{ aField : @s(A, B, C, D) } | { "aField" : "C" } |
If a list parameter is given, the value producer randomly selects a value from that list by default.
Template | Generated Json |
---|---|
{ aField : @s(length=10) } | { "aField" : "awpVXpJTxb" } |
{ aField : @s(min=10, max=20) } | { "aField" : "AgPkUNKonauaxJgct" } |
If a map parameter is given, the value producer produces a value according to the map values.
Following is the table about whether each type of parameter is supported by the pre-installed producers.
producer | none | single | list | map |
---|---|---|---|---|
@smart | no, produce null | yes | no | no |
@s | yes | yes | yes | yes, supported parameters: length, max, min |
@i | yes | yes | yes | yes, supported parameters: max, min |
@f | yes | yes | yes | yes, supported parameters: max, min |
@b | yes | yes | yes | no |
@raw | no | yes | no | no |
@ip | yes | no | no | no |
@ipv6 | yes | no | no | no |
@base64 | yes | no | no | yes, supported parameters: length |
@iso8601 | yes | no | no | no |
@cat | yes | yes | yes | no |
Template | Generated Json |
---|---|
{ anObject : { aField : @s, bField : @s } } | { "anObject" : { "aField" : "hhnNc", "bField" : "EyHbB" } } |
A json object consists of a set of properties. Each property can be specified with a value producer. The default type is @smart which is implicitly used.
Template | Generated Json |
---|---|
@s[](3) | [ "hwhCL", "tDcPO", "OgdGC" ] |
@s[](1, 10) | [ "QwWxg", "ytaGY", "NGZBr", "DsBKx", "MvwSb", "qsEXA", "YHkxC" ] |
Array tag [] indicates producing a json array.
The default value producer for the array elements is placed before []
.
The size configuration of the generated array is placed after []
.
(3)
means size of 3 and it is a shorthand of(size=3)
(1, 10)
means the size range is between 1 and 10 and it is a short hand of(min=1, max=10)
Template | Generated Json |
---|---|
@s[ 1, 2, 3, 4 ] | [ "1", "2", "3", "4" ] |
@s[ 1, 2, 3, 4 ](6) | [ "1", "2", "3", "4", "qRTWm", "RTBik" ] |
@s[ 1, @i(2), @b(false), @s(4) ] | [ "1", 2, false, "4" ] |
- In the first example, it produces string elements.
- In the second example, the size is greater than the amount of the listed elements. The extra elements will be filled by the value producer. In this case, the values are random strings of length 5. If the size is not greater, all listed elements are remained without filled elements. Same rule applies to the range size.
- In the third example, each elements can have its own value producer the it overwrites the default value producer.
Template | Generated Json |
---|---|
@address : { city : @s, street : @s, number : @i }, { office : @address, home : @address } | { "office" : { "city" : "MavBr", "street" : "odcjd", "number" : 79 }, "home" : { "city" : "zdNCm", "street" : "UsBcv", "number" : 63 } } |
A value producer @x
can be used for value producer declaration.
The declaration can be before or after the json root, separated by comma ,
.
The order between multiple declarations do not matter.
Template | Generated Json | |
---|---|---|
@s { fieldA, fieldB, fieldC: @i } | { "fieldA" : "yUiIE", "fieldB" : "vrMwv" "fieldC" : 54 } |
In the above example, the default value producer is explicitly specified as @s
.
If nothing is specified, @smart
is used. In case of @s
, it supports none parameters.
Therefore, the values of fieldA and fieldB can be omitted. @s
will generate
a random value form them.
The mechanism of searching the default value producer is the same as Java inheritance: It starts from itself to the root, util it finds a value producer.
JsonTemplate allows to inject variables to the template, it provides two methods to do that:
JsonTemplate.withVar(String, Object)
JsonTemplate.withVars(Map<String, Object>)
Template | Generated Json |
---|---|
{ name : $name } | { "name" : "John" } |
In the above example, token $
indicates a variable. Variable name
refers to a string John
.
Template | Generated Json |
---|---|
{ letters : $letters } | { "letters" : [ "A", "B", "C" ] } |
In the above example, variable letters
refers to an array ["A", "B", "C"] or a collection with
elements "A", "B", "C".
Template | Generated Json |
---|---|
{ person : $person } | { "person" : { "languages" : [ "Chinese", "English", "Dutch" ], "name" : "Haihan", "age" : 33, "male" : true } } |
In the above example, variable person
refers to an map object.
Variables can be also put in the parameters of a value producer.
When variable used as a single parameter, the parameter type (single, list, or map) is adjusted according to the type of the variable.
- If the variable refers to a collection or an array, it becomes a list parameter;
- If the variable refers to map, it becomes a map parameter;
- Otherwise, it keeps as a single parameter;
When variable used as list or map parameter, the semantics won't change.
JsonTemplate does not aim for providing the full-fledged value generation. Other libraries, such as Guava, Apache Commons, JFaker, etc., provide powerful value generation apis.
The pre-installed value producers are designed in a way which can be extended.
With JsonTemplate.withValueProducer(IValueProducer)
, users can freely
extend the pre-installed values producers or create new ones.
Above is just a peek for the list of features. For more examples, examples.txt provides part of the logs in tests.
If you have issues, great ideas, or comments, please let us know. We have a mailing list located at: jsontemplate2019@gmail.com