首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring + Tiles2 + Freemarker --通过Freemarker Servlet或Spring的FreeMarkerViewResolver进行集成?

Spring + Tiles2 + Freemarker --通过Freemarker Servlet或Spring的FreeMarkerViewResolver进行集成?
EN

Stack Overflow用户
提问于 2008-10-24 14:55:04
回答 1查看 3.3K关注 0票数 7

我今天在努力从Freemarker迁移到Tiles2 + Freemarker。

我的freemarker模板使用来自spring.ftl的宏。

如果我在web.xml中提供了一个fremarker servlet,我的模型对freemarker是可见的,但是特定的spring变量(自然地)不会被填充到模型中,因为springs FreemarkerView会负责这一点。

如果我为特定url (比如"/tpl/*")配置一个单独的DispatcherServlet,并将freemarker解析器配置为servlet的默认视图解析器,并提供UrlFilenameViewController作为默认控制器,则会将特殊的spring变量填充到模型中,但我自己的模型是不可见的:它被绑定为请求属性。我可以通过${Request.mymodel.myvar}访问我的模型,但通过这种方式,我必须更改所有的freemarker模板,并且我在想法中看到了一些难闻的东西。

现在我的解决方案是扩展UrlFilenameViewController并将我的模型从request添加到ModelAndView:

代码语言:javascript
复制
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)  {
        ModelAndView mav = super.handleRequestInternal(request, response);

        HashMap<String, Object> map = new HashMap<String, Object>();

        Enumeration<String> attributes = request.getAttributeNames();

        while(attributes.hasMoreElements()) {
            String attribute = attributes.nextElement();

            if("model".equals(attribute)) {
                logger.debug("FreemarkerViewController.handleRequestInternal: putting attribute to model: " + attribute + "=" + request.getAttribute(attribute));
                map.put(attribute, request.getAttribute(attribute));
            }
        }
        logger.debug("FreemarkerViewController.handleRequestInternal: VIEW: " + mav.getViewName());
        return new ModelAndView(mav.getViewName(), map);
    }

但是这个解决方案也有些难闻--如果我在我的业务控制器中向模型中添加了一些东西,我必须在这里添加它。

我的问题有没有一个很好的解决方案?

EN

回答 1

Stack Overflow用户

发布于 2013-02-09 05:54:43

我记得我在两个项目中解决了同样的问题。您的第二种方法几乎是正确的(FreeMarkerViewResolver),但是如果我没记错的话,我还必须从FreeMarkerViewTilesView扩展,以显式地将这两个模型桥接在一起。

自定义平铺视图:

代码语言:javascript
复制
public class CustomTilesView extends TilesView {

    @Override
    protected void exposeModelAsRequestAttributes(Map model, HttpServletRequest request) {
        request.setAttribute(CustomFreeMarkerView.MODEL_KEY, model);
    }
}

自定义FreeMarker视图:

代码语言:javascript
复制
public class CustomFreeMarkerView extends FreeMarkerView {

    public static final String MODEL_KEY = FreeMarkerView.class.getName() + ".MODEL";

    @Override
    protected void exposeHelpers(Map model, HttpServletRequest request) throws Exception {
        super.exposeHelpers(model, request);
        final Map savedModel = (Map) request.getAttribute(MODEL_KEY);
        if (savedModel != null) {
            mergeModels(model, savedModel);
        }
    }

    private void mergeModels(Map<String, Object> targetModel, Map<String, Object> recipientModel) throws ServletException {
        for (Map.Entry<String, Object> entry : recipientModel.entrySet()) {
            String key = entry.getKey();
            if (targetModel.containsKey(key)) {
                throw new ServletException("Cannot merge models because of an existing model object of the same name: " + key);
            }
            targetModel.put(key, entry.getValue());
        }
    }
}

在Spring中注册:

代码语言:javascript
复制
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"
      p:viewClass="com.my.CustomTilesView"
      p:contentType="text/html;charset=UTF-8"/>

<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"
      p:suffix=".ftl"
      p:exposeSpringMacroHelpers="true"
      p:viewClass="com.my.CustomFreeMarkerView"
      p:contentType="text/html;charset=UTF-8"/>

应该行得通。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/233881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档