如何从 Freemarker TemplateDirectiveModel 访问 Spring RequestContext

发布于 2024-11-10 07:56:59 字数 675 浏览 1 评论 0原文

我使用 Spring MVC 和 Freemarker 作为视图技术。我有一个 TemplateDirectiveModel 对象,需要在执行方法中访问 Spring 的 RequestContext 。目前我是这样做的:

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();
    }
}

但我不敢相信这是正确的方法。我有一种感觉,我错过了一些重要的事情。也许 Spring 中有处理 Freemarker 指令的特殊类和注释?也许我可以让 Spring 将一些东西注入到指令类中,通过它我可以访问 Spring 请求范围?

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 missed 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

终陌 2024-11-17 07:56:59

您可以子类化FreeMarkerConfigurer,重写其postProcessConfiguration(Configuration config)方法。
您的实现只需在配置中添加一个请求感知依赖项,作为 共享变量示例(由 FM文档)。

应该可以解决这个问题,Spring风格......

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...

阳光下的泡沫是彩色的 2024-11-17 07:56:59

有一种更简单的方法可以做到这一点。如果您已经在使用 spring 的 FreeMarkerConfigurer,则可以向其提供变量映射:

<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>

现在至少在扩展 TemplateDirectiveModel 的执行方法的类中,您可以访问该注入的属性。

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();
    }       
}

现在在您的 .ftl 中您可以使用:

<@macroName />;

并且它将自动注入 spring 依赖项。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文