Class FreemarkerView
- All Implemented Interfaces:
View
@RestOp-annotated methods to ask the framework to
render an Apache FreeMarker template.
Companion to FreemarkerMixin and FreemarkerViewRenderer: the mixin sets
up the /freemarker/* mount and registers the renderer; the renderer detects
FreemarkerView returns in the response-processor chain and asks the configured
freemarker.template.Configuration to getTemplate(templateName) and then
process(dataModel, writer) directly onto the response writer.
Usage:
The template name is configuration-relative — the configured
freemarker.template.Configuration template loader prepends its own resource root. With
the bridge's default configuration + basePath("/templates/"),
FreemarkerView.of("hello.ftlh") resolves to /templates/hello.ftlh on the
classpath.
.ftl vs .ftlh auto-escape:
FreeMarker auto-selects HTML escaping by file extension: .ftlh templates emit
HTML-escaped output (variable references are escaped automatically), while .ftl
templates emit raw output. For HTML responses, prefer the .ftlh extension to avoid an
XSS regression sneaking in via a future attribute-binding change.
Template suffix:
The templateSuffix(...) builder
knob lets the bridge append a suffix (e.g. ".ftlh") to template names that don't
already end with it, so callers can write FreemarkerView.of("hello") and have the
bridge resolve it as "hello.ftlh" on the classpath (idempotent — explicit suffix
is honored).
Immutability:
Each attr(...) / attrs(...) / header(...) call returns a new
FreemarkerView carrying the additional binding; the original instance is unchanged.
This keeps FreemarkerView a value type safe to share across requests (e.g. as a static
singleton built once and returned from many handlers).
See Also:
- Since:
- 10.0.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceMarker for an attribute value that promises to be adopted during the render (unwrapped from the data model by some directive and applied to render-scoped state), and wants the render to fail if that never happens instead of silently behaving as if the attribute was absent. -
Method Summary
Modifier and TypeMethodDescriptionReturns a copy of this view with the given attribute added (or replaced if a binding forkeyalready exists).Returns a copy of this view with all entries from the given map added (or replaced if a binding for any key already exists).The attributes to expose to the template.Optional response headers applied by the renderer before forwarding to the templating engine.The name of the template to render — typically a path relative to the mixin-configured base path.Returns a copy of this view with the given response header set on the rendered response.static FreemarkerViewCreates a newFreemarkerViewcarrying the given template name and no attributes.toString()
-
Method Details
-
of
Creates a newFreemarkerViewcarrying the given template name and no attributes.The template name is configuration-relative; the configured
freemarker.template.Configurationtemplate loader supplies the prefix (resource root). With the bridge's default configuration +basePath("/templates/"), the name"hello.ftlh"resolves to/templates/hello.ftlhon the classpath.- Parameters:
templateName- The template name (configuration-relative, suffix optional when the mixin'stemplateSuffixis configured). Must not benullor blank.- Returns:
- A new
FreemarkerViewinstance. - Throws:
IllegalArgumentException- IftemplateNameisnullor blank.
-
attr
Returns a copy of this view with the given attribute added (or replaced if a binding forkeyalready exists).The full attribute map is passed to FreeMarker as the data model, so each entry is accessible inside the template as
${key}.nullvalues are rejected at build-time because FreeMarker's default null-handling renders missing/null bindings as an error or empty string depending on configuration, which typically masks what is a caller bug; rejecting up-front surfaces the mistake at the call site (matches the Thymeleaf / Mustache bridge precedents).- Parameters:
key- The attribute key (exposed inside the template as${key}). Must not benullor blank.value- The attribute value. Must not benull.- Returns:
- A new
FreemarkerViewcarrying the additional attribute. - Throws:
IllegalArgumentException- Ifkeyisnullor blank, orvalueisnull.
-
attrs
Returns a copy of this view with all entries from the given map added (or replaced if a binding for any key already exists).- Parameters:
values- The attributes to add.nullis treated as an empty map (the result is the same instance with no entries added).- Returns:
- A new
FreemarkerViewcarrying the additional attributes. - Throws:
IllegalArgumentException- If any entry has anull/blank key or anullvalue.
-
header
Returns a copy of this view with the given response header set on the rendered response.Typical usage:
.header("Content-Type", "text/html; charset=UTF-8")or.header("Cache-Control", "no-store"). The renderer applies these headers viaHttpServletResponse.setHeader(...)before writing the rendered output.- Parameters:
name- The header name. Must not benullor blank.value- The header value. Must not benull.- Returns:
- A new
FreemarkerViewcarrying the additional response header. - Throws:
IllegalArgumentException- Ifnameisnullor blank, orvalueisnull.
-
getTemplateName
Description copied from interface:ViewThe name of the template to render — typically a path relative to the mixin-configured base path.For example,
"hello.jsp"with a JSP mixinbasePath("/WEB-INF/views/")resolves to"/WEB-INF/views/hello.jsp"on the request dispatcher.- Specified by:
getTemplateNamein interfaceView- Returns:
- The template name. Never
null.
-
getAttributes
Description copied from interface:ViewThe attributes to expose to the template.Each entry is forwarded to the templating engine as a named binding accessible from inside the template (e.g.
${name}in JSP / EL,th:text="${name}"in Thymeleaf).- Specified by:
getAttributesin interfaceView- Returns:
- The attributes map. Never
null; returns an immutable empty map when no attributes are bound.
-
getResponseHeaders
Description copied from interface:ViewOptional response headers applied by the renderer before forwarding to the templating engine.Typical use cases: setting
Content-Type(e.g."text/html; charset=UTF-8") orCache-Controlon the rendered response. The default implementation returns an empty map so mostViewimpls don't need to override it.- Specified by:
getResponseHeadersin interfaceView- Returns:
- An immutable map of headers to apply. Never
null; defaults to an empty map.
-
toString
-