3

我正在尝试使用 htmlunit、junit 和 freemarker 模板进行 freemarker 单元测试。但是当我使用 <@spring.message "data"> 它给了我这个例外。

freemarker.core.InvalidReferenceException: Expression springMacroRequestContext is undefined on line 89, column 134 in spring.ftl.
at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:125)
at freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:135)
at freemarker.core.Dot._getAsTemplateModel(Dot.java:78)
at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
at freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:86)
at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
at freemarker.core.Expression.getStringValue(Expression.java:93)
at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.IfBlock.accept(IfBlock.java:82)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.Macro$Context.runMacro(Macro.java:172)
at freemarker.core.Environment.visit(Environment.java:614)
at freemarker.core.UnifiedCall.accept(UnifiedCall.java:106)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.Macro$Context.runMacro(Macro.java:172)
at freemarker.core.Environment.visit(Environment.java:614)
at freemarker.core.UnifiedCall.accept(UnifiedCall.java:106)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:221)
at freemarker.core.Environment.process(Environment.java:199)
at freemarker.template.Template.process(Template.java:237)

关于这个例外的任何想法,我该如何解决这个问题?提前感谢您的帮助。

4

3 回答 3

4

我不确定处理这个问题的正确方法是什么,因为我只花了大约一个小时试图自己解决这个问题。但是对我有用的是使用以下命令手动将“springMacroRequestContext”添加到数据模型中:

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
model.put("springMacroRequestContext", new RequestContext(request, null, null, null));

请注意,这仍然必须在有效请求中发生。因此,这可能不适用于 cron 作业或计划任务,因为没有当前请求。

于 2012-08-17T20:00:46.897 回答
1

您需要在 Spring controllerContext.xml 中配置 Freemarker View Resolver。具体来说,添加:

<property name="exposeSpringMacroHelpers" value="true"/>

所以它看起来像:

<bean id="freemarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <property name="cache" value="true"/>
    <property name="prefix" value=""/>
    <property name="suffix" value=".ftl"/>
    <property name="exposeSpringMacroHelpers" value="true"/>
    <property name="exposeSessionAttributes" value="true"/>
    <property name="contentType" value="text/html;charset=UTF-8"/>
</bean>
于 2015-02-19T23:23:58.783 回答
1

扩展 Brad Parks 关于手动添加的答案springMacroRequestContext

对(如果您的对象是 WebApplicationContext 中的 bean,则WebApplicationContext可以轻松访问)的引用就足够了,因为您可以模拟请求:@Autowired

// Declare WebApplicationContext as an instance variable
@Autowired
WebApplicationContext ctx;

// Then in the method...:
    // (The mock object is from the org.springframework.mock.web package)
    MockHttpServletRequest req = new MockHttpServletRequest();
    // secret sauce:
    req.setAttribute(RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE, ctx);
    // Create a MacroRequestContext for Freemarker to use
    model.put("springMacroRequestContext", new RequestContext(req));
于 2016-10-13T14:44:11.337 回答