我正在尝试创建一个自定义FreemarkerConfigurationFactory,它帮助我启用设置一些设置,以便我可以访问ftl模板中的方法。问题是我找不到获取ServletContext
的方法。
ServletContextListener
接口,该接口最初工作,但我很快就发现每次请求都会重新创建FreeMarkerConfigurationFactory。所以在第一次通话后它就消失了。可以将这个变量保持在某个地方的静态,但它只是闻起来很糟糕,我确信我做错了。知道如何才能正确获取ServletContext
的实例吗?
public class FreeMarkerConfigurationFactory implements FreemarkerConfigurationFactory, ServletContextListener {
Configuration configuration;
public FreeMarkerConfigurationFactory() {
this.configuration = new Configuration(new freemarker.template.Version(2, 3, 22));
BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_21);
builder.setExposeFields(true);
ObjectWrapper wrapper = builder.build();
configuration.setObjectWrapper(wrapper);
}
@Override
public Configuration getConfiguration() {
return this.configuration;
}
@Override
public void contextInitialized(ServletContextEvent sce) {
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
我创造了以下内容,对我来说看起来并不那么糟糕。
@WebListener
public final class FreeMarkerConfigurationFactory implements FreemarkerConfigurationFactory, ServletContextListener {
@Override
public Configuration getConfiguration() {
return Instance.getConfiguration();
}
@Override
public void contextInitialized(ServletContextEvent sce) {
Instance.setServletContext(sce.getServletContext());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
private static class Instance {
private static Configuration configuration;
static {
configuration = new Configuration(new freemarker.template.Version(2, 3, 22));
BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_22);
builder.setExposeFields(true);
ObjectWrapper wrapper = builder.build();
configuration.setObjectWrapper(wrapper);
}
public static void setServletContext(ServletContext context) {
configuration.setServletContextForTemplateLoading(context, "/");
}
public static Configuration getConfiguration() {
return configuration;
}
}
}
我宁愿不使用静态类。如果有人能告诉我如何以更好的方式访问ServletContext,我很乐意听到它!
我删除了BeansWrapperBuild并将其替换为DefaultObjectWrapperBuilder。到目前为止,一切都运作良好!
@WebListener
public final class FreeMarkerConfigurationFactory implements FreemarkerConfigurationFactory, ServletContextListener {
@Override
public Configuration getConfiguration() {
return Instance.getConfiguration();
}
@Override
public void contextInitialized(ServletContextEvent sce) {
Instance.setServletContext(sce.getServletContext());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// Ignore
}
private static class Instance {
private static Configuration configuration;
static {
configuration = new Configuration(new freemarker.template.Version(2, 3, 22));
DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(new freemarker.template.Version(2, 3, 22));
builder.setExposeFields(true);
DefaultObjectWrapper wrapper = builder.build();
configuration.setObjectWrapper(wrapper);
}
public static void setServletContext(ServletContext context) {
configuration.setServletContextForTemplateLoading(context, "/");
}
public static Configuration getConfiguration() {
return configuration;
}
}
}