我正在尝试使用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)
关于这个例外的任何想法,我如何解决这个问题?提前感谢您的帮助。
答案 0 :(得分:4)
我不确定处理这个的正确方法是什么,因为我花了大约一个小时试图弄清楚这一点。但是对我来说有用的是使用以下方法手动将“springMacroRequestContext”添加到数据模型中:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
model.put("springMacroRequestContext", new RequestContext(request, null, null, null));
请注意,这仍然必须在有效请求中发生。因此,这可能不适用于cron作业或计划任务,因为当前没有请求。
答案 1 :(得分: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>
答案 2 :(得分:1)
扩展Brad Parks关于手动添加springMacroRequestContext
:
对WebApplicationContext
(如果您的对象是WebApplicationContext中的bean)可以使用@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));