2

我开始使用 Spring MVC 编写应用程序,然后决定改用 Tapestry。我想保留我最初使用的无 XML 配置方法。我首先尝试了这个:

public class ServletConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        // Spring //
        AnnotationConfigWebApplicationContext rootContext = new
        AnnotationConfigWebApplicationContext();
        rootContext.register(PersistenceContext.class, ApplicationContext.class);
        servletContext.addListener(new ContextLoaderListener(rootContext));

        // Tapestry //
        servletContext.setInitParameter("tapestry.app-package", "...");
        FilterRegistration.Dynamic filter = servletContext.addFilter("app", TapestrySpringFilter.class);
        filter.addMappingForUrlPatterns(null, false, "/*");
    }
}

这里的问题是 Tapestry 使用空的构造函数创建了另一个 ContextLoaderListener。它不接收 WebApplicationContext,而是查看 contextClass 和 contextConfigLocation 初始化参数。所以我尝试了这个:

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    // Spring //
    servletContext.setInitParameter("contextClass",
            "org.springframework.web.context.support.AnnotationConfigWebApplicationContext");
    servletContext
            .setInitParameter(
                    "contextConfigLocation",
                    "...config.PersistenceContext ...config.ApplicationContext");

    // Tapestry //
    servletContext.setInitParameter("tapestry.app-package", "...");
    FilterRegistration.Dynamic filter = servletContext.addFilter("app", TapestrySpringFilter.class);
    filter.addMappingForUrlPatterns(null, false, "/*");
}

这导致了这个:

 java.lang.IllegalArgumentException: When using the Tapestry/Spring integration library, you must specifiy a context class that extends from org.apache.tapestry5.spring.TapestryApplicationContext. Class org.springframework.web.context.support.AnnotationConfigWebApplicationContext does not. Update the 'contextClass' servlet context init parameter.

TapestryApplicationContext 继承自 org.springframework.web.context.support.XmlWebApplicationContext。所以我的问题是:有没有办法使基于注释的配置与这种方法一起工作?如果没有,是否有另一种方法可以让我使用它?或者有没有办法避免 XML?

我尝试恢复到我在这里放置的第一个版本的 ServletConfig,但我添加了

servletContext.setInitParameter("tapestry.use-external-spring-context", "true");

我不再收到错误消息,但页面也没有加载。当我尝试加载 /app/,而不是加载索引页面时,我得到了这个:

<html>
    <head>
        <title>Error</title>
    </head>
    <body>/app/index.jsp</body>
</html>

我不确定是什么原因造成的,我在日志中找不到任何表明任何问题的内容。我认为调度程序服务存在某种问题。有没有人见过这种类型的错误?我不确定这是否与我原来的问题无关,或者这是否是我的方法无效的症状。如果有人可以告诉我这是一个单独的问题,我将采取适当的措施。

4

1 回答 1

1

开箱即用的spring 集成需要一个 XML 文件。

扩展SpringModuleDef并覆盖locateApplicationContext以返回AnnotationConfigApplicationContext不会太难

然后,您将编写自己的TapestrySpringFilter实现来加载新的 SpringModuleDef 子类。

- 编辑 - -

我错了,挂毯弹簧集成用于WebApplicationContextUtils.getWebApplicationContext(servletContext)查找ApplicationContext。因此,您可以在加载 TapestryStringFilter 之前使用 ApplicationContext 初始化 servlet 上下文,它应该可以正常工作。

例如

ApplicationContext myContext = createAnnotationBasedAppContext();
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, myContext);
于 2013-07-23T16:28:00.470 回答