public class FreemarkerServlet
extends javax.servlet.http.HttpServlet
<url-pattern>*.ftl<url-pattern>
). See web.xml example (and more) in the FreeMarker Manual!
Main features
Request
, RequestParameters
, Session
, and Application
variables.
Application.attrName
, Session.attrName
, Request.attrName
is not mandatory;
it's enough to write attrName
, and if no such variable was created in the template, it will search the
variable in Request
, and then in Session
, and finally in Application
.
JspTaglibs
that can be used to load JSP taglibs. For example:<#assign dt=JspTaglibs["http://displaytag.sf.net"]>
or
<#assign tiles=JspTaglibs["/WEB-INF/struts-tiles.tld"]>
.
include_page
allows you to include the output of another servlet resource from
your servlet container, just as if you used ServletRequest.getRequestDispatcher(path).include()
:
<@include_page path="/myWebapp/somePage.jsp"/>
. You can also pass parameters to the newly included page by
passing a hash named params
:
<@include_page path="/myWebapp/somePage.jsp" params= lang: "en", q="5"}/>
. By default, the request
parameters of the original request (the one being processed by FreemarkerServlet) are also inherited by the include.
You can explicitly control this inheritance using the inherit_params
parameter:
<@include_page path="/myWebapp/somePage.jsp" params={lang: "en", q="5"} inherit_params=false/>
.
Supported init-param
-s
classpath:
, like in classpath:com/example/templates, to indicate that
you want to load templates from the specified package accessible through the Thread Context Class Loader of the
thread that initializes this servlet.incompatible_improvements
is set to 2.3.22 (or higher), you can specify multiple comma separated locations
inside square brackets, like: [ WEB-INF/templates, classpath:com/example/myapp/templates ]
.
This internally creates a MultiTemplateLoader
. Note again that if incompatible_improvements
isn't
set to at least 2.3.22, the initial [
has no special meaning, and so this feature is unavailable.class://
prefix, like in
class://com/example/templates format, which is similar to classpath:
, except that it uses the
defining class loader of this servlet's class. This can cause template not found errors, if that class (in
freemarer.jar
usually) is not local to the web application, while the templates are.<param-value>256 KB</param-value>
) then in kilobytes or megabytes.
This corresponds to ServletResponse.setBufferSize(int)
. If the HttpServletResponse
state doesn't
allow changing the buffer size, it will silently do nothing. If this init param isn't specified, then the buffer size
is not set by FreemarkerServlet
in the HTTP response, which usually means that the default buffer size of the
servlet container will be used.false
(default,
but not recommended), if a template is requested that's missing, this servlet responses with a HTTP 404 "Not found"
error, and only logs the problem with debug level. If true
(recommended), the servlet will log the issue with
error level, then throws an exception that bubbles up to the servlet container, which usually then creates a HTTP 500
"Internal server error" response (and maybe logs the event into the container log). See "Error handling" later for
more!<param-value>classpath:.*myoverride.*\.jar$, webInfPerLibJars, classpath:.*taglib.*\.jar$</param-value>
, or
<param-value>classpath</param-value>
. (Whitespace around the commas and list items will be ignored.) See
TaglibFactory.setMetaInfTldSources(List)
for more information. Defaults to a list that contains
"webInfPerLibJars" only (can be overridden with
createDefaultMetaInfTldSources()
). Note that this can be also specified with the
"org.freemarker.jsp.metaInfTldSources" system property. If both the init-param and the system property
exists, the sources listed in the system property will be added after those specified by the init-param. This is
where the special entry, "clear" comes handy, as it will remove all previous list
items. (An intended usage of the system property is setting it to clear, classpath
in the Eclipse run
configuration if you are running the application without putting the dependency jar-s into WEB-INF/lib
.)
Also, note that further classpath:<pattern>
items are added automatically at the end of this list based on
Jetty's "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern"
servlet context attribute.TaglibFactory.setClasspathTlds(List)
. Whitespace around the list items will be ignored. Defaults to no paths
(can be overidden with createDefaultClassPathTlds()
). Note that this can also be specified with the
"org.freemarker.jsp.classpathTlds" system property. If both the init-param and the system property exists, the
items listed in system property will be added after those specified by the init-param.TemplateUpdateInterval
, DefaultEncoding
, ObjectWrapper
, TemplateExceptionHandler
.
Instead, use init-params with the setting names documented at Configuration.setSetting(String, String)
, such
as object_wrapper
.
Configuration
-level FreeMarker setting. See
the possible names and values at Configuration.setSetting(String, String)
.Error handling
Notes:
Logger
), under the "freemarker.servlet" category.ServletException
to the servlet container is mentioned at a few places below. That in practice
usually means HTTP 500 "Internal server error" response, and maybe a log entry in the servlet container's log.Errors types:
true
(recommended), it will instead log the problem with error level, then the servlet throws ServletException
to
the servlet container (with the proper cause exception). After all, if the visited URL had an associated "action" but
the template behind it is missing, that's an internal server error, not a wrong URL.ServletException
to the servlet container (with the proper cause exception).template_exception_handler
init-param is rethrow
(recommended), it will log it with error level and then the servlet throws
ServletException
to the servlet container (with the proper cause exception). But beware, the default value of
the template_exception_handler
init-param is html_debug
, which is for development only! Set it to
rethrow
for production. The html_debug
(and debug
) handlers will print error details to the
page and then commit the HTTP response with response code 200 "OK", thus, the server wont be able roll back the
response and send back an HTTP 500 page. This is so that the template developers will see the error without digging
the logs.
Modifier and Type | Field and Description |
---|---|
protected boolean |
debug
Deprecated.
Not used anymore; to enable/disable debug logging, just set the logging level of the logging library
used by
Logger . |
static String |
INIT_PARAM_BUFFER_SIZE
Init-param name - see the
FreemarkerServlet class documentation about the init-params. |
static String |
INIT_PARAM_CLASSPATH_TLDS
Init-param name - see the
FreemarkerServlet class documentation about the init-params. |
static String |
INIT_PARAM_CONTENT_TYPE
Init-param name - see the
FreemarkerServlet class documentation about the init-params. |
static String |
INIT_PARAM_EXCEPTION_ON_MISSING_TEMPLATE
Init-param name - see the
FreemarkerServlet class documentation about the init-params. |
static String |
INIT_PARAM_META_INF_TLD_LOCATIONS
Init-param name - see the
FreemarkerServlet class documentation about the init-params. |
static String |
INIT_PARAM_NO_CACHE
Init-param name - see the
FreemarkerServlet class documentation about the init-params. |
static String |
INIT_PARAM_TEMPLATE_PATH
Init-param name - see the
FreemarkerServlet class documentation about the init-params. |
static String |
KEY_APPLICATION |
static String |
KEY_APPLICATION_PRIVATE |
static String |
KEY_INCLUDE |
static String |
KEY_JSP_TAGLIBS |
static String |
KEY_REQUEST |
static String |
KEY_REQUEST_PARAMETERS |
static String |
KEY_REQUEST_PRIVATE |
static String |
KEY_SESSION |
static String |
META_INF_TLD_LOCATION_CLASSPATH
Used as part of the value of the "MetaInfTldSources" init-param.
|
static String |
META_INF_TLD_LOCATION_CLEAR
Used as part of the value of the "MetaInfTldSources" init-param.
|
static String |
META_INF_TLD_LOCATION_WEB_INF_PER_LIB_JARS
Used as part of the value of the "MetaInfTldSources" init-param.
|
static long |
serialVersionUID |
static String |
SYSTEM_PROPERTY_CLASSPATH_TLDS
When set, the items defined in it will be added after those coming from the
"ClasspathTlds" init-param.
|
static String |
SYSTEM_PROPERTY_META_INF_TLD_SOURCES
When set, the items defined in it will be added after those coming from the
"MetaInfTldSources" init-param.
|
Constructor and Description |
---|
FreemarkerServlet() |
Modifier and Type | Method and Description |
---|---|
protected Configuration |
createConfiguration()
Creates the FreeMarker
Configuration singleton and (when overidden) maybe sets its defaults. |
protected List |
createDefaultClassPathTlds()
Creates the default of the "ClasspathTlds" init-param; if this init-param is specified, it
will be appended after the default, not replace it.
|
protected List |
createDefaultMetaInfTldSources()
Creates the default of the "MetaInfTldSources" init-param; if this init-param is
specified, it will completelly replace the default value.
|
protected ObjectWrapper |
createDefaultObjectWrapper()
Override this to specify what the default
ObjectWrapper will be when the
object_wrapper Servlet init-param wasn't specified. |
protected TemplateModel |
createModel(ObjectWrapper objectWrapper,
javax.servlet.ServletContext servletContext,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) |
protected ObjectWrapper |
createObjectWrapper()
Called from
init() to create the ObjectWrapper ; to customzie this aspect, in most cases you
should override createDefaultObjectWrapper() instead. |
protected HttpRequestParametersHashModel |
createRequestParametersHashModel(javax.servlet.http.HttpServletRequest request) |
protected TaglibFactory |
createTaglibFactory(ObjectWrapper objectWrapper,
javax.servlet.ServletContext servletContext)
Called to create the
TaglibFactory once per servlet context. |
protected TemplateLoader |
createTemplateLoader(String templatePath)
Create the template loader.
|
protected Locale |
deduceLocale(String templatePath,
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Returns the locale used for the
Configuration.getTemplate(String, Locale) call. |
void |
doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) |
void |
doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) |
protected Configuration |
getConfiguration()
Returns the
Configuration object used by this servlet. |
protected ObjectWrapper |
getObjectWrapper()
Should be final; don't override it.
|
protected String |
getTemplatePath()
Deprecated.
Not called by FreeMarker code, and there's no point to override this (unless to cause confusion).
|
void |
init()
Don't override this method to adjust FreeMarker settings! Override the protected methods for that, such as
createConfiguration() , createTemplateLoader(String) , createDefaultObjectWrapper() ,
etc. |
protected void |
initializeServletContext(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Called when servlet detects in a request processing that
application-global (that is, ServletContext-specific) attributes are not yet
set.
|
protected void |
initializeSession(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Called when servlet detects in a request processing that session-global
(that is, HttpSession-specific) attributes are not yet set.
|
protected void |
postTemplateProcess(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
Template template,
TemplateModel data)
Called after the execution returns from template.process().
|
protected boolean |
preprocessRequest(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
Called as the first step in request processing, before the templating mechanism
is put to work.
|
protected boolean |
preTemplateProcess(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response,
Template template,
TemplateModel data)
Called before the execution is passed to template.process().
|
protected String |
requestUrlToTemplatePath(javax.servlet.http.HttpServletRequest request)
Maps the request URL to a template path (template name) that is passed to
Configuration.getTemplate(String, Locale) . |
protected void |
setConfigurationDefaults()
Sets the defaults of the configuration that are specific to the
FreemarkerServlet subclass. |
doDelete, doHead, doOptions, doPut, doTrace, getLastModified, service, service
public static final long serialVersionUID
public static final String INIT_PARAM_TEMPLATE_PATH
FreemarkerServlet
class documentation about the init-params. (This init-param
has existed long before 2.3.22, but this constant was only added then.)public static final String INIT_PARAM_NO_CACHE
FreemarkerServlet
class documentation about the init-params. (This init-param
has existed long before 2.3.22, but this constant was only added then.)public static final String INIT_PARAM_CONTENT_TYPE
FreemarkerServlet
class documentation about the init-params. (This init-param
has existed long before 2.3.22, but this constant was only added then.)public static final String INIT_PARAM_BUFFER_SIZE
FreemarkerServlet
class documentation about the init-params.public static final String INIT_PARAM_META_INF_TLD_LOCATIONS
FreemarkerServlet
class documentation about the init-params.public static final String INIT_PARAM_EXCEPTION_ON_MISSING_TEMPLATE
FreemarkerServlet
class documentation about the init-params.public static final String INIT_PARAM_CLASSPATH_TLDS
FreemarkerServlet
class documentation about the init-params.public static final String SYSTEM_PROPERTY_META_INF_TLD_SOURCES
public static final String SYSTEM_PROPERTY_CLASSPATH_TLDS
public static final String META_INF_TLD_LOCATION_WEB_INF_PER_LIB_JARS
public static final String META_INF_TLD_LOCATION_CLASSPATH
public static final String META_INF_TLD_LOCATION_CLEAR
public static final String KEY_REQUEST
public static final String KEY_INCLUDE
public static final String KEY_REQUEST_PRIVATE
public static final String KEY_REQUEST_PARAMETERS
public static final String KEY_SESSION
public static final String KEY_APPLICATION
public static final String KEY_APPLICATION_PRIVATE
public static final String KEY_JSP_TAGLIBS
protected boolean debug
Logger
.public void init() throws javax.servlet.ServletException
createConfiguration()
, createTemplateLoader(String)
, createDefaultObjectWrapper()
,
etc. Also note that lot of things can be changed with init-params instead of overriding methods, so if you
override settings, usually you should only override their defaults.init
in class javax.servlet.GenericServlet
javax.servlet.ServletException
protected TemplateLoader createTemplateLoader(String templatePath) throws IOException
ClassTemplateLoader
if the template
path starts with "class://"
, a FileTemplateLoader
if the template path starts with
"file://"
, and a WebappTemplateLoader
otherwise. Also, if
incompatible_improvements
is 2.3.22 or higher,
it will create a MultiTemplateLoader
if the template path starts with "["
.templatePath
- the template path to create a loader forIOException
public void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException
doGet
in class javax.servlet.http.HttpServlet
javax.servlet.ServletException
IOException
public void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException
doPost
in class javax.servlet.http.HttpServlet
javax.servlet.ServletException
IOException
protected Locale deduceLocale(String templatePath, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException
Configuration.getTemplate(String, Locale)
call. The base implementation
simply returns the locale setting of the configuration. Override this method to provide different behaviour, i.e.
to use the locale indicated in the request.templatePath
- The template path (templat name) as it will be passed to Configuration.getTemplate(String)
.
(Not to be confused with the servlet init-param of identical name; they aren't related.)javax.servlet.ServletException
- Can be thrown since 2.3.22, if the locale can't be deduced from the URL.protected TemplateModel createModel(ObjectWrapper objectWrapper, javax.servlet.ServletContext servletContext, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws TemplateModelException
TemplateModelException
protected TaglibFactory createTaglibFactory(ObjectWrapper objectWrapper, javax.servlet.ServletContext servletContext) throws TemplateModelException
TaglibFactory
once per servlet context.
The default implementation configures it based on the servlet-init parameters and various other environmental
settings, so if you override this method, you should call super, then adjust the result.TemplateModelException
protected List createDefaultClassPathTlds()
The implementation in FreemarkerServlet
returns TaglibFactory.DEFAULT_CLASSPATH_TLDS
.
protected List createDefaultMetaInfTldSources()
The implementation in FreemarkerServlet
returns TaglibFactory.DEFAULT_META_INF_TLD_SOURCES
.
List
of TaglibFactory.MetaInfTldSource
-s; not null
.protected String requestUrlToTemplatePath(javax.servlet.http.HttpServletRequest request) throws javax.servlet.ServletException
Configuration.getTemplate(String, Locale)
. You can override it (i.e. to provide advanced rewriting
capabilities), but you are strongly encouraged to call the overridden method first, then only modify its return
value.request
- The currently processed HTTP requestnull
. This is what's passed to
Configuration.getTemplate(String)
later. (Not to be confused with the templatePath
servlet init-param of identical name; that basically specifies the "virtual file system" to which this
will be relative to.)javax.servlet.ServletException
- Can be thrown since 2.3.22, if the template path can't be deduced from the URL.protected boolean preprocessRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException
request
- the HTTP requestresponse
- the HTTP responsejavax.servlet.ServletException
IOException
protected Configuration createConfiguration()
Configuration
singleton and (when overidden) maybe sets its defaults. Servlet
init-params will be applied later, and thus can overwrite the settings specified here.
By overriding this method you can set your preferred Configuration
setting defaults, as only the settings
for which an init-param was specified will be overwritten later. (Note that FreemarkerServlet
also has
its own defaults for a few settings, but since 2.3.22, the servlet detects if those settings were already set
here and then it won't overwrite them.)
The default implementation simply creates a new instance with Configuration.Configuration()
and returns
it.
protected void setConfigurationDefaults()
FreemarkerServlet
subclass.
This is called after the common (wired in) FreemarkerServlet
setting defaults was set, also theprotected ObjectWrapper createObjectWrapper()
init()
to create the ObjectWrapper
; to customzie this aspect, in most cases you
should override createDefaultObjectWrapper()
instead. Overriding this method is necessary when you want
to customize how the ObjectWrapper
is created from the init-param values, or you want to do some
post-processing (like checking) on the created ObjectWrapper
. To customize init-param interpretation,
call GenericServlet.getInitParameter(String)
with Configurable.OBJECT_WRAPPER_KEY
as argument, and see if it
returns a value that you want to interpret yourself. If was null
or you don't want to interpret the
value, fall back to the super method.
The default implementation interprets the object_wrapper
servlet init-param with
calling Configurable.setSetting(String, String)
(see valid values there), or if there's no such servlet
init-param, then it calls createDefaultObjectWrapper()
.
ObjectWrapper
that will be used for adapting request, session, and servlet context attributes
to TemplateModel
-s, and also as the object wrapper setting of Configuration
.protected ObjectWrapper createDefaultObjectWrapper()
ObjectWrapper
will be when the
object_wrapper
Servlet init-param wasn't specified. Note that this is called by
createConfiguration()
, and so if that was also overidden but improperly then this method might won't be
ever called. Also note that if you set the object_wrapper
in createConfiguration()
, then this
won't be called, since then that has already specified the default.
The default implementation calls Configuration.getDefaultObjectWrapper(freemarker.template.Version)
. You
should also pass in the version paramter when creating an ObjectWrapper
that supports that. You can get
the version by calling getConfiguration()
and then Configuration.getIncompatibleImprovements()
.
protected ObjectWrapper getObjectWrapper()
createObjectWrapper()
instead.protected final String getTemplatePath()
TemplatePath
init-param. null
if the template_loader
setting was set in
a custom createConfiguration()
.protected HttpRequestParametersHashModel createRequestParametersHashModel(javax.servlet.http.HttpServletRequest request)
protected void initializeServletContext(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException
request
- the actual HTTP requestresponse
- the actual HTTP responsejavax.servlet.ServletException
IOException
protected void initializeSession(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException
request
- the actual HTTP requestresponse
- the actual HTTP responsejavax.servlet.ServletException
IOException
protected boolean preTemplateProcess(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Template template, TemplateModel data) throws javax.servlet.ServletException, IOException
Example: Expose the Serlvet context path as "baseDir" for all templates:
((SimpleHash) data).put("baseDir", request.getContextPath() + "/"); return true;
request
- the actual HTTP requestresponse
- the actual HTTP responsetemplate
- the template that will get executeddata
- the data that will be passed to the template. By default this will be
an AllHttpScopesHashModel
(which is a SimpleHash
subclass).
Thus, you can add new variables to the data-model with the
SimpleHash.put(String, Object)
subclass) method.javax.servlet.ServletException
IOException
protected void postTemplateProcess(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Template template, TemplateModel data) throws javax.servlet.ServletException, IOException
request
- the actual HTTP requestresponse
- the actual HTTP responsetemplate
- the template that was executeddata
- the data that was passed to the templatejavax.servlet.ServletException
IOException
protected Configuration getConfiguration()
Configuration
object used by this servlet.
Please don't forget that Configuration
is not thread-safe
when you modify it.