获取FreemarkerConfigurationFactory的ServletContext

时间:2015-04-04 18:16:11

标签: java freemarker jersey-2.0

我正在尝试创建一个自定义FreemarkerConfigurationFactory,它帮助我启用设置一些设置,以便我可以访问ftl模板中的方法。问题是我找不到获取ServletContext的方法。

  • @Context注入不起作用,因为我不在资源类
  • 我尝试添加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) {
    }
}

更新:1

我创造了以下内容,对我来说看起来并不那么糟糕。

@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,我很乐意听到它!


更新:2

我删除了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;
        }
    }
}

0 个答案:

没有答案