我正在将一组grails 2.0.4应用程序迁移到版本3.x。它们全部与许多Java应用程序一起部署在同一服务器上。使用sitemesh和freemarker模板,这两组Java和grails应用程序都具有相同的外观。
但是在grails 3.x中,我无法使用通用装饰,因此该应用程序坚持使用layouts/main.gsp来呈现我的gsp。

到目前为止(grass 2.0.4),提供一个普通的装饰是相当直截了当的。每个grails应用程序的/WEB-INF/decorators.xml文件都提供了对适用的freemarker模板的引用。而且web.xml包括sitemesh过滤器以及freemarker装饰器servlet声明和映射。

decorators.xml:

<?xml version="1.0" encoding="UTF-8"?>
<decorators defaultdir="/">
    <excludes>
        <pattern>/ND/*</pattern>
        <pattern>/*/ND/*</pattern>
     </excludes>
     <decorator name="freemarker" page="myftl.ftl">
         <pattern>/*</pattern>
     </decorator>
</decorators>

来自web.xml的Sitemesh过滤器和freemarker servlet:
<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>
<servlet>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <servlet-class>com.opensymphony.module.sitemesh.freemarker.FreemarkerDecoratorServlet</servlet-class>
    <init-param>
      <param-name>TemplatePath</param-name>
      <param-value>class://</param-value>
    </init-param>
    <init-param>
      <param-name>default_encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <url-pattern>*.ftl</url-pattern>
</servlet-mapping>

我尝试过的
  • 我已经将decorators.xml移动到src/main/webapp/WEB-INF下
  • 在grails 3.x中不再存在sitemesh过滤器,因此,我删除了sitemesh.xml
  • 不使用
  • web.xml,所以现在我在spring/resources.groovy上定义了freemarker servlet:

  • resources.groovy:
    beans = {
        sitemeshFreemarkerServlet(ServletRegistrationBean) {
            servlet = bean(FreemarkerDecoratorServlet)
            urlMappings = ["*.ftl"]
            loadOnStartup = 2
        }
    }
    

    但是,grails 3.x应用程序坚持使用layouts/main.gsp渲染我的gsp页面。似乎decorators.xml没有得到处理。我想念什么?

    最佳答案

    也许是一个丑陋的hack,但是您可以将sitemesh处理叠加到一个网格上:

  • 在Application类(或spring/resources.groovy)中注册自定义sitemesh过滤器:
  • @Bean FilterRegistrationBean sitemeshFilterRegistrationBean() { FilterRegistrationBean reg=new FilterRegistrationBean() reg.setFilter(new MySitemeshFilter()); reg.setInitParameters(["configFile":"WEB-INF/my.sitemesh.xml"]) reg.setUrlPatterns(["/*"]) reg.setDispatcherTypes(DispatcherType.REQUEST,DispatcherType.ERROR); reg.setOrder(0); return reg; }
  • sitemesh配置不得为默认配置,因为grails仍在继续
    阅读
  • 注册freemarker servlet来处理ftl:
  • @Bean ServletRegistrationBean freeMarkerServletRegistrationBean(){ ServletRegistrationBean reg=new ServletRegistrationBean(new FreemarkerDecoratorServlet(),"*.ftl"); reg.addInitParameter("TemplatePath", "class://"); reg.addInitParameter("default_encoding", "UTF-8"); // etc return reg; }
  • 添加自定义sitemesh过滤器:
  • import com.opensymphony.module.sitemesh.Config;import com.opensymphony.module.sitemesh.Factoryimport com.opensymphony.module.sitemesh.factory.DefaultFactory;import com.opensymphony.sitemesh.ContentProcessor;import com.opensymphony.sitemesh.DecoratorSelector;import com.opensymphony.sitemesh.compatability.DecoratorMapper2DecoratorSelector;import com.opensymphony.sitemesh.webapp.SiteMeshWebAppContext;import grails.util.Holders;import javax.servlet.FilterConfigclass MySitemeshFilter extends com.opensymphony.sitemesh.webapp.SiteMeshFilter { private static final String MY_SITEMESH_FACTORY = "my.sitemesh.factory"; private FilterConfig filterConfig; @Override public void init(FilterConfig filterConfig) { super.init(filterConfig); filterConfig.getServletContext().setAttribute("grailsApplication", Holders.grailsApplication); this.filterConfig=filterConfig; } protected Factory getFactory(FilterConfig filterConfig) { Config config=new Config(filterConfig) Factory f=(Factory)config.getServletContext().getAttribute(MY_SITEMESH_FACTORY); if (f==null) { f=new DefaultFactory(config); config.getServletContext().setAttribute(MY_SITEMESH_FACTORY, f); } return f; } @Override protected DecoratorSelector initDecoratorSelector(SiteMeshWebAppContext webAppContext) { Factory factory = getFactory(filterConfig); factory.refresh(); return new DecoratorMapper2DecoratorSelector(factory.getDecoratorMapper()); }}
  • 在此过滤器中,您必须覆盖新的sitemesh工厂中的装饰器选择器,原因是默认的选择器是单例(sic),并且grails已将其注册为其内部gsp处理
  • 您的不应具有来覆盖内容处理器(initContentProcessor方法),以便使用默认的sitemesh工厂
  • 来使grails处理gsp。
  • 如果要获取更多功能(如排除的模式),则需要覆盖整个doFilter方法,以便在contentProcessor.handles(webAppContext)中使用新的contentProcessor
  • 在src/main/webapp/WEB-INF中将my.sitemesh.xml和decorators.xml添加到
  • 我已在过滤器初始化中将grailsApplication添加到servlet上下文中,因此您可以在ftl模板中使用它
  • 如果要跳过某些布局,请在内部grails布局中按环境添加条件
  • 关于grails - 在Grails 3中使用Sitemesh,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35157053/

    10-10 03:47