public static void main(String[] args) throws IOException {
port(8080);
Configuration config = new Configuration(Configuration.VERSION_2_3_26);
config.setDirectoryForTemplateLoading(new File("PATH_NAME"));
get("/test", (req,res) ->{
StringWriter writer = new StringWriter();
Template temp = config.getTemplate("loginform.ftl");
temp.process(null, writer);
return writer;
});
post("/select", (req,res) -> {
String city = req.queryParams("city");
String state = req.queryParams("state");
Map<String, Object> data = new HashMap<>();
data.put("Hello", "Your not null!");
StringWriter writer = new StringWriter();
Template temp = config.getTemplate("result.ftl");
temp.process(data, writer);
return writer;
});
}
Above is the main method to the Spark application i am developing. It involves two templates, loginform.ftl and result.ftl. Loginform.ftl is a simple html form that sends a post request to the server which handled by the post handler in the code above. When I fill out the form and send the request, i get a 500 internal server error. The error relates to the result.ftl which, right now, i am using to test template making. I am passing a HashMap to the result.ftl template. The error i get is:
FreeMarker template error:
The following has evaluated to null or missing:
==> data [in template "result.ftl" at line 2, column 8]
FTL stack trace ("~" means nesting-related):
- Failed at: #list data as key, value [in template "result.ftl" at line
2, column 1]
----
I took this to mean that data was null when the template was being generated , but it very clearly isn't. I have no idea this is happening. My template files are below.
loginform.ftl
<form action= "/select" method= "POST" accept-charset="utf-8">
City Name: <input type= "text" name = "city">
State(2 letter format):<input type= "text" name = "state">
<input type= "submit" id = "submitButton">
</form>
result.ftl
<html>
<#list data as key, value>
${key} = ${value};
</#list>
</html>
The error message is right. In your Java code
data
is used as the data-model root. The root itself is not a top-level variable, but the container of the top-level variables. So for example${Hello}
would work, and print "Your not null!". (Also note that "data" is just a local variable name, which is gone during Java compilation, and you never pass the "data" variable name to FreeMarker.) So you should make aroot
Map
(or bean), put thedata
Map
(or bean) into it, and passroot
toTemplate.process
.Update: That is, where now you have
temp.process(data, writer);
, you should have: