How to access Spring RequestContext from a Freemarker TemplateDirectiveModel
I'm using Spring MVC with Freemarker as view technologie. I have a TemplateDirectiveModel object which needs to access Spring's RequestContext within the execute method. Currently I do it like this:
public class MyDirective implements TemplateDirectiveModel
{
public void execute(Environment env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException
{
StringModel model = (StringModel) env.getGlobalVariable("springMacroRequestContext");
RequestContext requestContext = (RequestContext) model.getWrappedObject();
}
}
But I can't believe that this is the right way to do it. I have the feeling I mis开发者_如何学Pythonsed something important. Maybe there are special classes and annotations for handling Freemarker direcives in Spring? Maybe I can let Spring inject something into the directive class with which I can access Springs request scope?
You could subclass FreeMarkerConfigurer
, overriding its postProcessConfiguration(Configuration config)
method.
Your implementation would just put a request-aware dependency in the configuration, as a shared variable for example (as preconised by the FM documentation).
Should do the trick, Spring-style...
There is an easier way to do this. If you are already using spring's FreeMarkerConfigurer, you can hand it a map of variables:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"
p:templateLoaderPath="/some_path_here">
<property name="freemarkerVariables">
<map>
<entry key='macroName' value-ref="templateModelRef" />
</map>
</property>
</bean>
<bean id="templateModelRef" class="...class..extends TemplateModel">
<property name="someResource" value-ref="resourceRef"/>
</bean>
Now at least in a class that extends TemplateDirectiveModel's execute method you have access to that injected property.
public class MyDirective extends TemplateDirectiveModel {
private MyResource someResource;
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars,TemplateDirectiveBody body) throws TemplateException, IOException {
StringModel sharedVariable = (StringModel)env.getConfiguration().getSharedVariable("beanName");
MyClass sweetness = (MyClass)sharedVariable.getWrappedObject();
}
}
Now in your .ftl you can use:
<@macroName />
and it will have spring dependencies auto injected.
精彩评论