p> Basic
Configuration is an object that stores common configuration information at the application level and global shared variables that can be used by the template. It is also responsible for the creation and caching of template instances. Configuration is actually an instance of the freemarker.template.Configuration object, created using its constructor. Typically, applications use a shared single instance Configuration object.
Configuration objects can be used by the Template object method. Each template instance is associated with a Configuration instance. It is associated with the Template constructor. Usually you use this method to obtain the template object by Configuration.getTemplate.
Shared variables
Shared variables are those defined for use by all templates. You can add shared variables through the setSharedVariable method of the configuration object.
Configuration cfg = new Configuration(); ... cfg.setSharedVariable("wrap", new WrapDirective()); cfg.setSharedVariable("company", "Foo Inc."); // Using ObjectWrapper.DEFAULT_WRAPPERAll template instances associated with this configuration object can obtain strings by obtaining the to_upper converter, company, and so you don't need to add these variables to root again and again. If you add a variable with the same name to root, the newly added variable will overwrite the previous shared variable.
warn!
If the configuration object is called multithreaded, do not use the TemplateModel implementation class as shared variables, because they are non-thread-safe, such as servlet-based web sites.
The Configuration object is initialized with some shared converter variables already:
Name class
Configuration parameters
Configuration parameters are those named parameters that can affect the operational behavior of FreeMarker. For example, locale, number_format.
The configuration parameters are stored in the Configuration instance, and they can be modified by the template instance. For example, if you set locale equal to "en_US" in Configuration, then all template objects will be used, "en_US" unless you use the setLocale method to modify the default configuration in a single template instance. Therefore, the parameters set by configuration can be regarded as default parameters, which can be overwritten by the parameters set at the first level of the Template, and the parameter information set by both can be overwritten by the parameters set in the environment (that is, the template file instructions set) as follows:
${1.2}<#setting locale="en_US">${1.2}You can imagine this calling method as 3 layers (configuration object layer, template layer, and running environment layer). The following table shows the settings for parameters of each layer:
Then the final results of the configuration parameters are: A = 1, B = 2, C = 3, D = 1, E = 2. The F parameter is likely to be null.
If you want to query a list of parameters that can be set, you can consult the following two parts of the FreeMarker API documentation:
All layers of configuration
freemarker.core.Configurable.setSetting(String, String)
Configuration layer configuration
freemarker.template.Configuration.setSetting(String,String)
Loading templates
Template loader
A template loader is an object that loads the original data based on an abstract path ("index.ftl" or "products/catalog.ftl"), and what kind of resources (file data in a directory or data in a database) is loaded depends on the specific loader implementation. When you call cfg.getTemplate, FreeMarker will ask you the template loader you configured to the Configuration object before, which is responsible for the file loading.
Built-in template loader <br />You can use the following three methods to set up template loading
void setDirectoryForTemplateLoading(File dir);
or
void setClassForTemplateLoading(Class cl, String prefix);
or
void setServletContextForTemplateLoading(Object servletContext, String path);
The first method above specifies a directory in a file system. FreeMarker will record the template in this directory. Needless to say, this directory must exist, or an exception will be thrown.
The second method uses a Class as an input parameter. When you want to use ClassLoader to load the template, you can use this method. This method will be called to find the template file. At the same time, this template loading method is more stable than the previous one, especially in production systems. You can easily package resource files, icons, etc. into .jar files.
The third method takes the context and base path of the web application (relative to the parent path of WEN-INF) as parameters. The template loader of this method will load the template from the web application context.
Loading templates from multiple locations
If you want to load templates from multiple locations, you can create a single template loader corresponding to different locations, and then wrap them in a template loader called MultiTemplateLoader, and finally set it to the Configuration object through the method setTemplateLoader (TemplateLoader loader). Here is an example of loading templates from two different locations:
import freemarker.cache.*; // template loaders live in this package ... FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates")); FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates")); ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), ""); TemplateLoader[] loaders = new TemplateLoader[] { ftl1, ftl2, ctl }; MultiTemplateLoader mtl = new MultiTemplateLoader(loaders); cfg.setTemplateLoader(mtl);FreeMarker will first search for the template file in the path /tmp/templates. If it is not found, then go back to the path /usr/data/templates. If it is not found, then try to load it in class-loader.
Get template files from other resources
If none of these built-in template loaders meet your requirements, you can customize a template loader yourself, just implement the freemarker.cache.TemplateLoader interface, and then pass it to the Configuration object through the method setTemplateLoader(TemplateLoader loader).
Cache template
FreeMarker caches templates means that when you get a template through the getTemplate method, FreeMarker will not only return a Template object, but also cache the object. When you request the template with the same path next time, it will return the template object in the cache. If you change the template file, then the next time you get the template, FreeMarker will automatically reload and re-parse the template. Despite this, if it is a time-consuming operation to directly determine whether a file has been modified, FreeMarker provides a configuration parameter "update delay" at the Configuration object level. This parameter means how long it takes for FreeMarker to determine the version of the template. The default setting is 5 seconds, which means that each 5 seconds will determine whether the template has been modified. If you want to make a real-time judgment, set this parameter to 0. Another thing to note is that not all loaders support this judgment method. For example, the template loader based on class-loader will not find that you have modified the template file.
This is how FreeMarker deletes the template in the cache, you can use the Configuration object method clearTemplateCache to manually clarify the template objects in the cache. In fact, the cache part can be added to FreeMarker as a component (that is, it can use a third-party cache scheme). You can achieve it by setting the cache_storage parameter. It is sufficient for most developers to implement freemarker.cache.MruCacheStorage that comes with FreeMarker. This cache uses 2 levels of Most Recently Used policy. At the first level, all cache entries use strong references: entries are not clear by the JVM, softly references that are relatively weak references. Until the maximum time is reached, those entries that are least recently used will be moved to the secondary cache. At this level, the entry is all weak referenced until it reaches expiration. If the size of the referenced and strong referenced regions can be set in the constructor, for example, if you want to set the strong referenced region to 20 and the weak referenced region to 250, you can use the following code:
cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250))
Since MruCacheStorage is the default cache implementation, you can also set it like this:
cfg.setSetting(Configuration.CACHE_STORAGE_KEY,"strong:20, soft:250");
When you create a new Configuration, it is implemented by default using the MruCacheStorage cache and the default value maxStrongSize is equal to 0, and maxSoftSize is equal to Integer.MAX_VALUE (that is, the theoretical maximum value). However, for high-load systems, we recommend setting maxStrongSize to a non-0 value, otherwise it will cause frequent reloading and re-parsing of the template.
Exception handling
Possible exceptions
Exceptions generated by FreeMarker can generally be classified into the following categories:
Exceptions generated in the initialization stage of FreeMarker : Usually, you only need to initialize FreeMarker once in your application, and the exception generated in this time period is called initialization exception.
Exceptions during the loading and parsing template : When you obtain the template through the Configuration.getTemplate() method (if the template is not cached before), two types of exceptions will be generated:
IOException: Because the template is not found, or other IO exceptions occur when reading the template, such as you do not have permission to read the file, etc.; freemarker.core.ParseException Because the syntax of the template file is incorrect;
Exceptions during execution: When you call the Template.process(...) method, two types of exceptions will be thrown:
IOException An error that occurs when writing data in output; freemarker.template.TemplatException other exceptions generated during runtime, such as the most common error is that the template refers to a variable that does not exist;