如何让 Spring 与 Wicket 配合良好? (ContextLoaderListener问题)

发布于 2024-11-17 09:45:18 字数 4729 浏览 0 评论 0 原文

据我所知,根据我找到的说明(例如 this),我需要在 web.xml 中使用这个才能让 Spring 工作:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

="http://www.mkyong.com/wicket/wicket-spring-integration-example/" rel="nofollow">这也是 我的 Wicket 应用程序类,我有:

public class MyApplication extends WebApplication {

    @Override
    protected void init() {
        super.init();    
        addComponentInstantiationListener(new SpringComponentInjector(this));
    }

    @Override
    public Class<? extends Page> getHomePage() {
        return HelloWorldPage.class;
    }
}

问题是,每当我在 web.xml 中有 ContextLoaderListener 时,Wicket 就不会启动。我只是收到 404 错误(或空白页),控制台输出如下:

SEVERE: Error listenerStart
Jun 28, 2011 12:49:04 PM org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [1,973] milliseconds.
Jun 28, 2011 12:49:04 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [] startup failed due to previous errors
Jun 28, 2011 12:49:04 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [] registered the JDBC driver [org.hsqldb.jdbc.JDBCDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Jun 28, 2011 12:49:04 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Jun 28, 2011 12:49:04 PM org.apache.catalina.startup.HostConfig deployDirectory

我正在使用两个框架的最新版本(Wicket 1.4.17 和 Spring 3.0.5),以及运行它们的 Tomcat 7(Tomcat 6 也会发生同样的情况)。另外,我在 WEB-INF/lib 中有以下 jar。缺少什么或太多?

antlr-2.7.6.jar                        log4j-1.2.16.jar              spring-web-3.0.5.jar
commons-collections-3.1.jar            mysql-connector-5.1.10.jar    slf4j-api-1.6.1.jar
dom4j-1.6.1.jar                        spring-beans-3.0.5.jar        slf4j-log4j12-1.6.1.jar
guava-r09.jar                          spring-context-3.0.5.jar      wicket-1.4.17.jar
hibernate-3.6.5.jar                    spring-core-3.0.5.jar         wicket-auth-roles-1.4.17.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar  spring-jdbc-3.0.5.jar         wicket-datetime-1.4.17.jar
hsqldb.jar                             spring-orm-3.0.5.jar          wicket-ioc-1.4.17.jar
javassist-3.12.0.GA.jar                spring-test-3.0.5.jar         wicket-spring-1.4.17.jar
jta-1.1.jar                            spring-transaction-3.0.5.jar  wicketstuff-annotation-1.4.17.2.jar

web.xml 的其余部分(我尝试使用 servlet 和过滤器设置 Wicket;没有区别):

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <display-name>My App</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <context-param>
        <param-name>configuration</param-name>
        <param-value>development</param-value>
    </context-param>

    <filter>
        <filter-name>MyApp</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
            <param-value>com.acme.MyApplication</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>MyApp</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

     <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

谷歌搜索我发现 有人遇到同样的问题,但没有解决方案。

有趣的是,我之前已经让 Spring 和 Wicket 很好地协同工作,并且设置几乎相同。有什么想法吗?

To my knowledge, and according to instructions I've found (like this and this too), I need this in web.xml for Spring to work:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

In my Wicket application class, I'd have:

public class MyApplication extends WebApplication {

    @Override
    protected void init() {
        super.init();    
        addComponentInstantiationListener(new SpringComponentInjector(this));
    }

    @Override
    public Class<? extends Page> getHomePage() {
        return HelloWorldPage.class;
    }
}

Problem is, whenever I have ContextLoaderListener in web.xml, Wicket doesn't start. I just get 404 errors (or blank page), and console output like:

SEVERE: Error listenerStart
Jun 28, 2011 12:49:04 PM org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [1,973] milliseconds.
Jun 28, 2011 12:49:04 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [] startup failed due to previous errors
Jun 28, 2011 12:49:04 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [] registered the JDBC driver [org.hsqldb.jdbc.JDBCDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Jun 28, 2011 12:49:04 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Jun 28, 2011 12:49:04 PM org.apache.catalina.startup.HostConfig deployDirectory

I'm using latest releases of both frameworks (Wicket 1.4.17 & Spring 3.0.5), and Tomcat 7 to run them on (the same thing happens with Tomcat 6). Also, I have the following jars in WEB-INF/lib. Something missing or too much?

antlr-2.7.6.jar                        log4j-1.2.16.jar              spring-web-3.0.5.jar
commons-collections-3.1.jar            mysql-connector-5.1.10.jar    slf4j-api-1.6.1.jar
dom4j-1.6.1.jar                        spring-beans-3.0.5.jar        slf4j-log4j12-1.6.1.jar
guava-r09.jar                          spring-context-3.0.5.jar      wicket-1.4.17.jar
hibernate-3.6.5.jar                    spring-core-3.0.5.jar         wicket-auth-roles-1.4.17.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar  spring-jdbc-3.0.5.jar         wicket-datetime-1.4.17.jar
hsqldb.jar                             spring-orm-3.0.5.jar          wicket-ioc-1.4.17.jar
javassist-3.12.0.GA.jar                spring-test-3.0.5.jar         wicket-spring-1.4.17.jar
jta-1.1.jar                            spring-transaction-3.0.5.jar  wicketstuff-annotation-1.4.17.2.jar

The rest of the web.xml (I've tried setting up Wicket with both servlet and filter; makes no difference):

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <display-name>My App</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <context-param>
        <param-name>configuration</param-name>
        <param-value>development</param-value>
    </context-param>

    <filter>
        <filter-name>MyApp</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
            <param-value>com.acme.MyApplication</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>MyApp</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

     <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

Googling around I found someone with the same problem, but no solutions.

Funny thing is, I've had Spring and Wicket working together nicely before, with pretty much identical setup. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

打小就很酷 2024-11-24 09:45:18

这是我的项目的配置:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <!-- Spring context config location(s) -->
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/applicationContext.xml
    </param-value>
    </context-param>  

    <display-name>afrodite</display-name>

    <!-- used by Log4jConfigListener -->
    <context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>afrodite.root</param-value>
    </context-param>     

    <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>   

    <filter>
    <filter-name>openSessionInView</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>

    <filter>
    <filter-name>afrodite-app</filter-name>
    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
    <init-param>
        <param-name>applicationClassName</param-name>
        <param-value>info.afrodite.wicket.AfroditeApplication</param-value>
    </init-param>
    <init-param>
        <param-name>configuration</param-name>
        <param-value>DEPLOYMENT</param-value>
    </init-param>
    </filter>    

    <!-- open session should be above the wicket filter -->
    <filter-mapping>
    <filter-name>openSessionInView</filter-name>
    <url-pattern>/app/*</url-pattern>
    </filter-mapping>     

    <filter-mapping>
    <filter-name>afrodite-app</filter-name>
    <url-pattern>/app/*</url-pattern>
    </filter-mapping>           

    <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
    <servlet-name>afrodite-api</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>afrodite-api</servlet-name>
    <url-pattern>/api/*</url-pattern>
    </servlet-mapping>    

    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

希望这会有所帮助。

This is a configuration of my project:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <!-- Spring context config location(s) -->
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/applicationContext.xml
    </param-value>
    </context-param>  

    <display-name>afrodite</display-name>

    <!-- used by Log4jConfigListener -->
    <context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>afrodite.root</param-value>
    </context-param>     

    <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>   

    <filter>
    <filter-name>openSessionInView</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>

    <filter>
    <filter-name>afrodite-app</filter-name>
    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
    <init-param>
        <param-name>applicationClassName</param-name>
        <param-value>info.afrodite.wicket.AfroditeApplication</param-value>
    </init-param>
    <init-param>
        <param-name>configuration</param-name>
        <param-value>DEPLOYMENT</param-value>
    </init-param>
    </filter>    

    <!-- open session should be above the wicket filter -->
    <filter-mapping>
    <filter-name>openSessionInView</filter-name>
    <url-pattern>/app/*</url-pattern>
    </filter-mapping>     

    <filter-mapping>
    <filter-name>afrodite-app</filter-name>
    <url-pattern>/app/*</url-pattern>
    </filter-mapping>           

    <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
    <servlet-name>afrodite-api</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>afrodite-api</servlet-name>
    <url-pattern>/api/*</url-pattern>
    </servlet-mapping>    

    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

Hope this will help.

伴我心暖 2024-11-24 09:45:18

请检查contextConfigLocationparam-value 应为classpath*:applicationContext.xml。请检查我的示例中的侦听器配置。希望我有帮助!

这是我的 web.xml 配置,效果很好:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
     version="2.4">

    <display-name>mywebapp</display-name>

    <filter>
        <filter-name>springRequestContextFilter</filter-name>
        <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <filter>
        <filter-name>wicket.mywebapp</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
            <param-value>com.company.example.web.MyApplication</param-value>
        </init-param>
    </filter>

        <!-- Enables Spring Security -->
    <filter>
        <filter-name>filterChainProxy</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
      <filter-name>filterChainProxy</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

 <filter-mapping>
  <filter-name>wicket.mywebapp</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

</web-app>

Please check contextConfigLocation. The param-value should be classpath*:applicationContext.xml. Please check the listeners configuration also in my example. Hope I helped!

This is my web.xml configuration which nicely works:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
     version="2.4">

    <display-name>mywebapp</display-name>

    <filter>
        <filter-name>springRequestContextFilter</filter-name>
        <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath*:applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <filter>
        <filter-name>wicket.mywebapp</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
            <param-name>applicationClassName</param-name>
            <param-value>com.company.example.web.MyApplication</param-value>
        </init-param>
    </filter>

        <!-- Enables Spring Security -->
    <filter>
        <filter-name>filterChainProxy</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
      <filter-name>filterChainProxy</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

 <filter-mapping>
  <filter-name>wicket.mywebapp</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

</web-app>
旧人九事 2024-11-24 09:45:18

编辑:后来我意识到这里的根本问题很可能是缺少日志配置。在我们的例子中(将 SLF4J 与 log4j 结合使用),在 log4j.properties 中添加正确的配置后,会出现各种警告和警告。即使使用 Tomcat,库记录的错误也变得可见。


我尝试使用 Jetty 而不是 Tomcat,并开始收到更好的错误消息。结果发现有几个库丢失了——我已经使用过的一些库所需的东西。

2011-06-28 15:57:01.879:WARN::Unable to reach node goal: started
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:184)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:640)

有些库显然需要我添加的公共日志记录。下一步:

java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor
    at org.springframework.context.support.AbstractRefreshableApplicationContext.customizeBeanFactory(AbstractRefreshableApplicationContext.java:218)

添加了 spring-asm。下一步:

org.springframework.beans.factory.BeanDefinitionStoreException: 
  Unexpected exception parsing XML document from class path resource [applicationContext.xml]; 
  nested exception is java.lang.NoClassDefFoundError: org/springframework/aop/config/AopNamespaceUtils

添加了 spring-aop。接下来是一些不太直接的事情:

org.springframework.beans.factory.BeanDefinitionStoreException: 
  Unexpected exception parsing XML document from class path resource [applicationContext.xml]; 
  nested exception is java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor

Spring 博客评论。显然它已从 spring-aop 中完全删除,您需要从以下位置获取 aopalliance.jar Sourceforge

(我认为这种沼泽是 Java EE 最糟糕的情况:我不知道 spring-asmspring-aop 是什么,更不用说 aopalliance > 做,但显然我需要它们:-P)

所以,添加了 aopalliance.jar。后来我还需要添加 spring-expression 和 cglib-2.2(Hibernate 自带的)。

之后,我的 Spring/Hibernate 持久层配置仍然存在一些问题,但它们超出了这个问题的范围。否则检票口和Spring 现在可以很好地工作(例如,用于在 Wicket 页面上注入服务层对象)。

我想这样做的一个寓意是,在某些情况下,Tomcat 会吃掉有用的错误消息,而 Jetty 可能更适合调试。另外,使用 Maven 可能会对依赖地狱有所帮助(但它也不是没有问题)。

Edit: Later on I realised the root problem here most likely was missing log configuration. In our case (using SLF4J with log4j), after adding proper configuration in log4j.properties all kinds of warnings & errors logged by libraries became visible, even with Tomcat.


I tried Jetty instead of Tomcat, and started getting better error messages. Turns out there were several libraries missing — stuff needed by some of the libraries I already used.

2011-06-28 15:57:01.879:WARN::Unable to reach node goal: started
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:184)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:640)

Some of the libs apparently require commons-logging, which I added. Next:

java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor
    at org.springframework.context.support.AbstractRefreshableApplicationContext.customizeBeanFactory(AbstractRefreshableApplicationContext.java:218)

Added spring-asm. Next:

org.springframework.beans.factory.BeanDefinitionStoreException: 
  Unexpected exception parsing XML document from class path resource [applicationContext.xml]; 
  nested exception is java.lang.NoClassDefFoundError: org/springframework/aop/config/AopNamespaceUtils

Added spring-aop. Next something a little less straight-forward:

org.springframework.beans.factory.BeanDefinitionStoreException: 
  Unexpected exception parsing XML document from class path resource [applicationContext.xml]; 
  nested exception is java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor

Found discussion about aopalliance missing in Spring blog comments. Apparently it has been completely removed from spring-aop, and you need to get aopalliance.jar from sourceforge.

(I think this kind of swamp is Java EE at its worst: I don't know what spring-asm or spring-aop let alone aopalliance do, but apparently I need them. :-P)

So, added aopalliance.jar. Later I still needed to add spring-expression and cglib-2.2 (which comes with Hibernate).

After that, some problems with my Spring/Hibernate persistence layer configuration remain, but they are out of scope for this question. Otherwise Wicket & Spring now work nicely (e.g. for injecting service layer objects on Wicket pages).

I guess one moral of this is that in some cases Tomcat eats useful error messages and Jetty might be better for debugging. Also, using Maven would have probably helped with the dependency hell somewhat (but it's not free of problems either).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文