Instead of a fixed response body, you can use a response template to build the response dynamically from the incoming request. MockServer supports three template engines:
Mustache Simple syntax, sections for loops and conditionals. Works on all JVM versions.
Velocity Apache Velocity — richer logic including loops, math, and JSON/XML parsing tools. Works on all JVM versions.
JavaScript Uses the Nashorn engine. Full ES6 support on Java 9–14. Deprecated in Java 11, removed in Java 15+.
JavaScript templates require the Nashorn JavaScript engine, which was deprecated in Java 11 and removed in Java 15. Do not use JavaScript templates if you are running MockServer on Java 15 or later.
Request model variables
Every template has access to a request object with the following fields:
Field Description request.methodHTTP method (e.g. GET) request.pathRequest path (e.g. /some/path) request.pathParametersMap of path parameter values (multi-value) request.queryStringParametersMap of query parameter values (multi-value) request.headersMap of header values (multi-value) request.cookiesMap of cookie values (single-value) request.bodyRequest body as an object request.bodyAsStringRequest body as a plain string request.securetrue for HTTPSrequest.keepAlivetrue if the client requested keep-aliverequest.remoteAddressClient IP address
Multi-value fields (headers, pathParameters, queryStringParameters) hold arrays. Access the first value with an index ([0] or .0).
Syntax by engine
Field Mustache Velocity JavaScript method {{ request.method }}$!request.methodrequest.methodpath {{ request.path }}$!request.pathrequest.pathfirst header value {{ request.headers.Accept.0 }}$!request.headers['Accept'][0]request.headers['Accept'][0]first query param {{ request.queryStringParameters.id.0 }}$!request.queryStringParameters['id'][0]request.queryStringParameters['id'][0]cookie value {{ request.cookies.session }}$!request.cookies['session']request.cookies['session']body {{ request.body }}$!request.bodyrequest.body
Dynamic built-in variables
All engines also expose these variables. Each call produces a fresh value:
Variable Description now_iso_8601Current datetime in ISO 8601 (2011-12-03T10:15:30Z) now_epochUnix epoch (seconds since Jan 1 1970) now_rfc_1123Current datetime in RFC 1123 (Tue, 3 Jun 2008 11:05:30 GMT) uuidRandom UUID string rand_int_10Random integer 0–9 rand_int_100Random integer 0–99 rand_bytes_1616 random bytes rand_bytes_3232 random bytes rand_bytes_6464 random bytes rand_bytes_128128 random bytes
Syntax follows the same engine conventions (e.g. {{ uuid }} in Mustache, $!uuid in Velocity, uuid in JavaScript).
Mustache templates
Mustache is the simplest option. Use {{ variable }} for substitution and {{# section }}...{{/ section }} for loops and conditionals.
Basic example
new ClientAndServer ( 1080 )
. when ( request (). withPath ( "/some/path" ))
. respond (
template (
HttpTemplate . TemplateType . MUSTACHE ,
"{ \n " +
" 'statusCode': 200, \n " +
" 'cookies': { \n " +
" 'session': '{{ request.headers.Session-Id.0 }}' \n " +
" }, \n " +
" 'headers': { \n " +
" 'Client-User-Agent': [ '{{ request.headers.User-Agent.0 }}' ] \n " +
" }, \n " +
" 'body': '{{ request.body }}' \n " +
"}"
)
);
Variables
{{ request.method }} prints the method. If the variable is unresolvable, an empty string is returned.
{
"statusCode": 200,
"body": {
"method": "{{ request.method }}",
"path": "{{ request.path }}",
"host": "{{ request.headers.host.0 }}"
}
}
Sections (loops, conditionals)
Sections iterate over arrays or act as if-statements. A section starts with {{# key }} and ends with {{/ key }}:
{
"statusCode": 200,
"body": "{'headers': '{{# request.headers.entrySet }}{{ key }}={{ value.0 }} {{/ request.headers.entrySet }}'}"
}
Use an inverted section {{^ -first }} to skip the first item (useful for comma-separated lists):
{
"statusCode": 200,
"body": "{'headers': [{{# request.headers.entrySet }}{{^ -first }}, {{/ -first }}'{{ key }}={{ value.0 }}'{{/ request.headers.entrySet }}]}"
}
JsonPath in Mustache
Extract values from a JSON request body using {{# jsonPath }}:
{
"statusCode": 200,
"body": "{'titles': {{# jsonPath }}$.store.book{{/ jsonPath }}[{{# jsonPathResult }}{{^ -first }}, {{/ -first }}'{{ title }}'{{/ jsonPathResult }}], 'bikeColor': '{{# jsonPath }}$.store.bicycle.color{{/ jsonPath }}{{ jsonPathResult }}'}"
}
XPath in Mustache
Extract values from an XML request body using {{# xPath }}:
{
"statusCode": 200,
"body": "{'titles': ['{{# xPath }}/store/book/title{{/ xPath }}', '{{# xPath }}//book[2]/title{{/ xPath }}'], 'bikeColor': '{{# xPath }}//bicycle/color{{/ xPath }}'}"
}
Velocity templates
Velocity uses $variable notation and supports #if, #foreach, and tool access.
Basic example
new ClientAndServer ( 1080 )
. when ( request (). withPath ( "/some/path" ))
. respond (
template (
HttpTemplate . TemplateType . VELOCITY ,
"{ \n " +
" 'statusCode': 200, \n " +
" 'cookies': { \n " +
" 'session': '$!request.headers['Session-Id'][0]' \n " +
" }, \n " +
" 'headers': { \n " +
" 'Client-User-Agent': [ '$!request.headers['User-Agent'][0]' ] \n " +
" }, \n " +
" 'body': '$!request.body' \n " +
"}"
)
);
Conditionals
#if($request.method == 'POST' && $request.path == '/somePath')
{
'statusCode': 200,
'body': "{'name': 'value'}"
}
#else
{
'statusCode': 406,
'body': "$!request.body"
}
#end
Loops
{
'statusCode': 200,
'body': "{'headers': [#foreach( $value in $request.headers.values() )'$value[0]'#if( $foreach.hasNext ), #end#end]}"
}
Parsing JSON bodies
Use the built-in $json tool:
#set($jsonBody = $json.parse($!request.body))
{
'statusCode': 200,
'body': "{'titles': [#foreach( $book in $jsonBody.store.book )'$book.title'#if( $foreach.hasNext ), #end#end]}"
}
Velocity REST API example
curl -v -X PUT "http://localhost:1080/mockserver/expectation" -d '{
"httpRequest": { "path": "/some/path" },
"httpResponseTemplate": {
"template": "{ \"statusCode\": 200, \"cookies\": { \"session\": \"$!request.headers[\"Session-Id\"][0]\" }, \"headers\": { \"Client-User-Agent\": [ \"$!request.headers[\"User-Agent\"][0]\" ] }, \"body\": \"$!request.body\" }",
"templateType": "VELOCITY"
}
}'
JavaScript templates
JavaScript templates use Nashorn and must return a response object.
Basic example
new ClientAndServer ( 1080 )
. when ( request (). withPath ( "/some/path" ))
. respond (
template (
HttpTemplate . TemplateType . JAVASCRIPT ,
"return { \n " +
" 'statusCode': 200, \n " +
" 'cookies': { \n " +
" 'session': request.headers['session-id'][0] \n " +
" }, \n " +
" 'headers': { \n " +
" 'Client-User-Agent': request.headers['User-Agent'] \n " +
" }, \n " +
" 'body': request.body \n " +
"};"
)
);
Reading the body as a string
Use request.bodyAsString when you need the body as a plain string (useful for JSON parsing):
template (
HttpTemplate . TemplateType . JAVASCRIPT ,
"return { statusCode: 200, headers: { Date: [ Date() ] }, body: JSON.stringify({is_active: JSON.parse(request.bodyAsString).is_active, id: '1234', name: 'taras'}) };"
)
Conditional logic and delay
String template = "" +
"if (request.method === 'POST' && request.path === '/somePath') { \n " +
" return { \n " +
" 'statusCode': 200, \n " +
" 'body': JSON.stringify({name: 'value'}) \n " +
" }; \n " +
"} else { \n " +
" return { \n " +
" 'statusCode': 406, \n " +
" 'body': request.body \n " +
" }; \n " +
"}" ;
new MockServerClient ( "localhost" , 1080 )
. when ( request (). withPath ( "/some/path" ))
. respond (
template ( HttpTemplate . TemplateType . JAVASCRIPT )
. withTemplate (template)
. withDelay ( TimeUnit . MINUTES , 2 )
);
JavaScript templates support ES6 syntax on Java 9–14 (Nashorn). On Java 15 and later, Nashorn is not available and JavaScript templates will not work. Use Mustache or Velocity instead.