开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜