Почему определение подстановочного знака Tiles REGEXP вызывает бесконечные jsp, включая ошибку - PullRequest
4 голосов
/ 29 июня 2011

Я использую плитки 2.2.2 со Struts2 2.2.3, поскольку плагин Struts2-Tiles довольно старый, в его реализации используется множество устаревших API Tiles, и я хочу попробовать подстановочный знак REGEXP, поэтому ниже я реализую свой собственный слушатель:

MyTilesContainerFactory

package tiles;

import org.apache.tiles.definition.pattern.DefinitionPatternMatcherFactory;
import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
import org.apache.tiles.definition.pattern.PrefixedPatternDefinitionResolver;
import org.apache.tiles.definition.pattern.regexp.RegexpDefinitionPatternMatcherFactory;
import org.apache.tiles.definition.pattern.wildcard.WildcardDefinitionPatternMatcherFactory;
import org.apache.tiles.factory.BasicTilesContainerFactory;


public class MyTilesContainerFactory extends BasicTilesContainerFactory {

  @Override
  protected <T> PatternDefinitionResolver<T> createPatternDefinitionResolver(Class<T> customizationKeyClass) {

    DefinitionPatternMatcherFactory wildcardFactory = new WildcardDefinitionPatternMatcherFactory();
    DefinitionPatternMatcherFactory regexpFactory = new RegexpDefinitionPatternMatcherFactory();
    PrefixedPatternDefinitionResolver<T> resolver = new PrefixedPatternDefinitionResolver<T>();
    resolver.registerDefinitionPatternMatcherFactory("WILDCARD", wildcardFactory);
    resolver.registerDefinitionPatternMatcherFactory("REGEXP", regexpFactory);
    return resolver;
  }
}

MyTilesInitializer

package tiles;

import org.apache.tiles.TilesApplicationContext;
import org.apache.tiles.factory.AbstractTilesContainerFactory;
import org.apache.tiles.startup.AbstractTilesInitializer;


public class MyTilesInitializer extends AbstractTilesInitializer {

  @Override
  protected AbstractTilesContainerFactory createContainerFactory(TilesApplicationContext context) {
    return new MyTilesContainerFactory();
  }

}

MyTilesListener

package tiles;

import org.apache.tiles.startup.TilesInitializer;
import org.apache.tiles.web.startup.AbstractTilesListener;


public class MyTilesListener extends AbstractTilesListener {

  @Override
  protected TilesInitializer createTilesInitializer() {
    return new MyTilesInitializer();
  }


}

Затем я определяю мой tile.xml

<tiles-definitions>
  <definition name="REGEXP:(.*)" template="/WEB-INF/tiles/basicLayout.jsp">
    <put-attribute name="header" value="/WEB-INF/tiles/header.jsp" />
    <put-attribute name="content" value="/WEB-INF/pages/{1}.jsp" />
    <put-attribute name="footer" value="/WEB-INF/tiles/footer.jsp" />
  </definition>
</tiles-definitions>

Когда я пытаюсь выполнить действие, которое возвращает результат тайлов, оно заканчивается бесконечным циклом с ошибкой включения jsp.

SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.StackOverflowError
    at java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
    at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:228)
    at java.io.File.exists(File.java:733)
    at sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:999)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:169)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at org.apache.jasper.compiler.ErrorDispatcher.createJavacError(ErrorDispatcher.java:526)
    at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:490)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:416)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:535)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:472)
    at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
    at org.apache.jasper.runtime.PageContextImpl.doInclude(PageContextImpl.java:638)
    at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:632)
    at org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:103)
    at org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:96)
    at org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
    at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
    at org.apache.tiles.renderer.impl.DefinitionAttributeRenderer.write(DefinitionAttributeRenderer.java:56)
    at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    at org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer.write(ChainedDelegateAttributeRenderer.java:76)
    at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
    at org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
    at org.apache.tiles.template.InsertAttributeModel.end(InsertAttributeModel.java:126)
    at org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:311)
    at org.apache.jsp.WEB_002dINF.tiles.basicLayout_jsp._jspx_meth_tiles_005finsertAttribute_005f0(basicLayout_jsp.java:128)
    at org.apache.jsp.WEB_002dINF.tiles.basicLayout_jsp._jspService(basicLayout_jsp.java:93)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:337)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:535)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:472)
    at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
    at org.apache.jasper.runtime.PageContextImpl.doInclude(PageContextImpl.java:638)
    at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:632)
    at org.apache.tiles.jsp.context.JspTilesRequestContext.include(JspTilesRequestContext.java:103)
    at org.apache.tiles.jsp.context.JspTilesRequestContext.dispatch(JspTilesRequestContext.java:96)
    at org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44)
    at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321)
    at org.apache.tiles.renderer.impl.DefinitionAttributeRenderer.write(DefinitionAttributeRenderer.java:56)
    at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    at org.apache.tiles.renderer.impl.ChainedDelegateAttributeRenderer.write(ChainedDelegateAttributeRenderer.java:76)
    at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670)
    at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:336)
    at org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:210)
    at org.apache.tiles.template.InsertAttributeModel.end(InsertAttributeModel.java:126)
    at org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:311)
    at org.apache.jsp.WEB_002dINF.tiles.basicLayout_jsp._jspx_meth_tiles_005finsertAttribute_005f0(basicLayout_jsp.java:128)
    at org.apache.jsp.WEB_002dINF.tiles.basicLayout_jsp._jspService(basicLayout_jsp.java:93)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
* 1023Может ли кто-нибудь дать мне совет?Я должен сказать, что если я не использовал определение подстановочного знака, то же определение работает нормально.Большое спасибо.

1 Ответ

4 голосов
/ 08 июля 2011

Я не совсем решил это, к своему удовлетворению, но я надеюсь, что это поможет.Регулярное выражение, которое вы используете, является, вероятно, самым жадным выражением, которое вы можете использовать.Он совпадает со всем, и это включает в себя все внутри самого определения плиток (basicLayout.jsp, header.jsp, footer.jsp).Это объясняет, почему вы получаете бесконечный цикл, поскольку ваше определение плиток REGEXP продолжает соответствовать каждому запросу файла и пытается удовлетворить каждый новый запрос файла новым вызовом шаблона (рекурсия шаблона!).

Страница поддержки Tiles Wildcard показывает несколько примеров.Ни один из этих примеров не использует (. *) - я думаю, мы только что выяснили, почему это может быть.

Вам нужно будет сделать ваш REGEXP немного менее жадным;Я знаю, что Struts использует немного другой подход для вызова плиток шаблона, но представьте, что у вас есть страница JSP, содержащая:

<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<tiles:insertDefinition name="somepage.tile" />

, и следующее определение плиток должно создать страницу шаблона, обернутую вокруг содержимого из / WEB-INF / pages / somepage.jsp :

<definition name="REGEXP:(.*)\.tile" template="/WEB-INF/tiles/basicLayout.jsp">
  <put-attribute name="header" value="/WEB-INF/tiles/header.jsp" />
  <put-attribute name="content" value="/WEB-INF/pages/{1}.jsp" />
  <put-attribute name="footer" value="/WEB-INF/tiles/footer.jsp" />
</definition>
...