如何指定 ObjectWrapper Freemarker
How to specify ObjectWrapper Freemarker
请帮帮我。我的网络应用程序使用 Spring MVC 和 Freemarker 2.3.23。当我开始申请时,我有: "WARNING: Custom EL functions won't be loaded because no ObjectWrapper was specified" 。我尝试通过以下几种方式指定 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?
查看 FreeMarkerConfigurer
的源代码:它在收到 ServletContext
时重新创建 TaglibFactory
,但不设置其 ObjectWrapper
。所以你需要覆盖那个方法,然后调用 taglibFactory.setObjectWrapper(configuration.getObjectWrapper())
。请注意,我假设 configuration
在那里总是最终的;我还没有检查过。 (我不建议使用其他 ObjectWrapper
,但 Configuration
包含的那个。所以你需要最后的 Configuration
。)
创建一个 FreeMarkerConfigurer
子类的实例,作为 @Bean
,让我们看看 Spring MVC 是否能接受它。 (我不知道,我没试过。)
如果有效,则应在 Spring Jira 中报告此修复。
谢谢@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;
}
}
我没有任何 "WARNING",但在我的注册页面上我无法收到错误消息。这条鳕鱼不起作用:
<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>
我哪里做错了?
最后,我重写了 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;
}
}
它似乎有效。
请帮帮我。我的网络应用程序使用 Spring MVC 和 Freemarker 2.3.23。当我开始申请时,我有: "WARNING: Custom EL functions won't be loaded because no ObjectWrapper was specified" 。我尝试通过以下几种方式指定 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?
查看 FreeMarkerConfigurer
的源代码:它在收到 ServletContext
时重新创建 TaglibFactory
,但不设置其 ObjectWrapper
。所以你需要覆盖那个方法,然后调用 taglibFactory.setObjectWrapper(configuration.getObjectWrapper())
。请注意,我假设 configuration
在那里总是最终的;我还没有检查过。 (我不建议使用其他 ObjectWrapper
,但 Configuration
包含的那个。所以你需要最后的 Configuration
。)
创建一个 FreeMarkerConfigurer
子类的实例,作为 @Bean
,让我们看看 Spring MVC 是否能接受它。 (我不知道,我没试过。)
如果有效,则应在 Spring Jira 中报告此修复。
谢谢@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;
}
}
我没有任何 "WARNING",但在我的注册页面上我无法收到错误消息。这条鳕鱼不起作用:
<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>
我哪里做错了?
最后,我重写了 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;
}
}
它似乎有效。