Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧&x2B;瓷砖2+;Freemarker-通过Freemarker Servlet或Spring集成';什么是Freemarkervewersolver?_Java_Spring_Tiles_Freemarker_Tiles2 - Fatal编程技术网

Java 弹簧&x2B;瓷砖2+;Freemarker-通过Freemarker Servlet或Spring集成';什么是Freemarkervewersolver?

Java 弹簧&x2B;瓷砖2+;Freemarker-通过Freemarker Servlet或Spring集成';什么是Freemarkervewersolver?,java,spring,tiles,freemarker,tiles2,Java,Spring,Tiles,Freemarker,Tiles2,我今天一直在努力尝试从Freemarker迁移到Tiles2+Freemarker 我的freemarker模板使用来自spring.ftl的宏 如果我在web.xml中提供一个fremarker servlet,我的模型对freemarker是可见的,但是特定的spring变量(自然)不会填充到模型中,因为springs FreemarkerView负责这一点 如果我为特定url(比如“/tpl/*”)配置一个单独的DispatcherServlet,并将freemarker解析器配置为该se

我今天一直在努力尝试从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并将我的模型从请求添加到ModelAndView:

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);
    }
protected ModelAndView HandlerRequestInternal(HttpServletRequest请求,HttpServletResponse响应){
ModelAndView mav=super.handleRequestInternal(请求、响应);
HashMap=newHashMap();
枚举属性=request.getAttributeNames();
while(attributes.hasMoreElements()){
字符串属性=attributes.nextElement();
如果(“模型”。等于(属性)){
logger.debug(“FreemarkerViewController.handleRequestInternal:将属性放入模型:”+attribute+“=”+request.getAttribute(属性));
map.put(属性,request.getAttribute(属性));
}
}
debug(“FreemarkerViewController.handleRequestInternal:VIEW:”+mav.getViewName());
返回新的ModelAndView(mav.getViewName(),map);
}
但是这个解决方案也有点难闻——如果我在业务控制器的模型中添加了一些东西,我必须在这里添加它


我的问题有一个优雅的解决方案吗?

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

自定义平铺视图:

public class CustomTilesView extends TilesView {

    @Override
    protected void exposeModelAsRequestAttributes(Map model, HttpServletRequest request) {
        request.setAttribute(CustomFreeMarkerView.MODEL_KEY, model);
    }
}
自定义自由标记视图:

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());
        }
    }
}
公共类CustomFreeMarkerView扩展了FreeMarkerView{
public static final String MODEL_KEY=FreeMarkerView.class.getName()+“.MODEL”;
@凌驾
受保护的void exposeHelpers(映射模型,HttpServletRequest)引发异常{
super.exposeHelpers(型号、请求);
最终映射savedModel=(Map)request.getAttribute(MODEL_键);
if(savedModel!=null){
合并模型(模型、保存的模型);
}
}
私有void mergeModels(Map targetModel、Map recipientModel)抛出ServletException{
对于(Map.Entry:recipientModel.entrySet()){
String key=entry.getKey();
if(targetModel.containsKey(关键)){
抛出新的ServletException(“无法合并模型,因为存在同名的模型对象:“+key”);
}
put(key,entry.getValue());
}
}
}
在春季登记两项:

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


应该有用。

你有没有找到更好的解决方案?我使用的是freemarker servlet和spring taglibs-它们通过特殊的spring freemarker宏处理我使用的所有内容。与