如何指定ObjectWrapper Freemarker

时间:2018-02-23 20:25:18

标签: spring freemarker

请帮帮我。我的Web应用程序使用Spring MVC和Freemarker 2.3.23。当我启动我的应用程序时,我有:“警告:因为没有指定ObjectWrapper,所以不会加载自定义EL函数”。我试图用以下几种方式指定ObjectWrapper:

@Configuration
public class CustomFreemarkerConfiguration extends WebMvcConfigurerAdapter {
@Bean
@Autowired
public TaglibFactory taglibFactory(ServletContext servletContext) throws 
 IOException, TemplateException {
    DefaultObjectWrapperBuilder owb = new 
DefaultObjectWrapperBuilder(freemarker.template.
Configuration.VERSION_2_3_23);
    owb.setForceLegacyNonListCollections(false);
    owb.setDefaultDateType(TemplateDateModel.DATETIME);
    DefaultObjectWrapper build = owb.build();
    TaglibFactory taglibFactory = new TaglibFactory(servletContext);
    taglibFactory.setObjectWrapper(build);
    return taglibFactory;
}
}

@Configuration
public class CustomFreemarkerConfiguration extends WebMvcConfigurerAdapter {
@Bean
public    DefaultObjectWrapper getDefaultObjectWrapper() {
    DefaultObjectWrapperBuilder defaultObjectWrapperBuilder = new 
DefaultObjectWrapperBuilder(freemarker.template.
Configuration.VERSION_2_3_23);
    defaultObjectWrapperBuilder.setExposeFields(true);
    DefaultObjectWrapper defaultObjectWrapper = 
defaultObjectWrapperBuilder.build();
    return defaultObjectWrapper;
}
}

@Configuration
public class CustomFreemarkerConfiguration extends WebMvcConfigurerAdapter {
...
@Bean
@Autowired
public TaglibFactory taglibFactory(ServletContext servletContext) throws 
IOException, TemplateException {
    FreeMarkerConfigurer freemarkerConfig = 
configFreeMarkerConfigurer(servletContext);

    TaglibFactory taglibFactory = freemarkerConfig.getTaglibFactory();

taglibFactory.setObjectWrapper(freemarker.template.Configuration.
getDefaultObjectWrapper(freemarker.template.Configuration.getVersion()));

    return taglibFactory;
}
...
}

但没有成功。也许某人有工作示例代码来指定ObjectWrapper?

3 个答案:

答案 0 :(得分:0)

查看FreeMarkerConfigurer的源代码:它会在收到TaglibFactory时重新创建ServletContext,但不会设置其ObjectWrapper。因此,您需要覆盖该方法,并调用taglibFactory.setObjectWrapper(configuration.getObjectWrapper())。请注意,我认为configuration始终是最终的;我还没有检查过。 (我不建议使用其他ObjectWrapper,而是使用Configuration包含的Configuration。所以您需要最终的FreeMarkerConfigurer。)

创建@Bean子类的实例,作为img.Save(),让我们看看Spring MVC是否选择了它。 (我不知道,我还没有尝试过。)

如果有效,那么应该在Spring Jira中报告此修复。

答案 1 :(得分:0)

谢谢@ddekany的回答,现在我的WebConfig看起来像这样:

 @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = "aquaplant")
    public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    public FreeMarkerConfigurer freeMarkerConfigurer;

    @Autowired
    public DefaultObjectWrapper defaultObjectWrapper;

    @Bean
    public ViewResolver getViewResolver() {
        FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
        resolver.setOrder(1);
        resolver.setSuffix(".ftl");
        resolver.setPrefix("");
        resolver.setExposeSpringMacroHelpers(true);
        resolver.setExposeRequestAttributes(true);
        resolver.setExposeSessionAttributes(true);
        resolver.setRequestContextAttribute("request");
        return resolver;
    }

    @Bean
    public FreeMarkerConfigurer getFreeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setTemplateLoaderPaths("/", "/WEB-INF/views");
        return configurer;
    }
    @Bean
    public DefaultObjectWrapper defaultObjectWrapper(){
        DefaultObjectWrapperBuilder owb=new DefaultObjectWrapperBuilder
                (freemarker.template.Configuration.VERSION_2_3_23);
        owb.setForceLegacyNonListCollections(false);
        DefaultObjectWrapper objectWrapper = owb.build();
        return objectWrapper;
    }
    @Bean
    @Autowired
    public TaglibFactory taglibFactory(ServletContext servletContext) throws
            IOException, TemplateException {
        freeMarkerConfigurer.setServletContext(servletContext);
        TaglibFactory taglibFactory = freeMarkerConfigurer.getTaglibFactory();
        taglibFactory.setObjectWrapper(defaultObjectWrapper);
        return taglibFactory;
    }

    }

我没有"警告",但在我的注册页面上我无法获得errorMessages。这个鳕鱼不工作:

  <div class="form-group">
        <@spring.bind "userForm"/>
          <#if spring.status.error>
            <div class="alert alert-danger" role="alert">
              <#list spring.status.errorMessages as error>
               <li>${error}</li>
              </#list>
            </div>
        </#if>
        <label for="username">Username</label>
        <input type="text" class="form-control" id="username" 
            placeholder="Username" name="username">    
  </div>

我在哪里弄错了?

答案 2 :(得分:0)

最后,我只是覆盖了getTaglibFactory():

import freemarker.ext.jsp.TaglibFactory;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

public class DefaultFreeMarkerConfigurer extends FreeMarkerConfigurer{
    @Override
    public TaglibFactory getTaglibFactory() {
        TaglibFactory tagLibFactory = super.getTaglibFactory();
        if (tagLibFactory.getObjectWrapper()==null) {
            tagLibFactory.setObjectWrapper(super.getConfiguration().getObjectWrapper());
        }
        return tagLibFactory;
    }
}

似乎工作正常。