0

使用的罐子的详细信息:Struts2 2.2.1 Spring 3.0.5.RELEASE Hibernate 3.6.0.FINAL

尝试执行映射如下的操作时遇到一个奇怪的问题:

<action name="supplierSearch" class="supplierSearchAction">
            <result>/pages/suppliersearch.jsp</result>
</action>
<action name="searchForSupplier" class="supplierSearchAction" method="doSearch">
<result>/pages/suppliersearch.jsp</result>
</action>

第一个操作将用户发送到搜索页面,他们输入搜索字符串,然后在发布表单时调用第二个操作。

spring config中的动作如下:

<bean id="supplierSearchAction"
    class="com.blah.SupplierSearchAction"
    scope="prototype">
    <property name="searchService" ref="supplierSearchService"></property>
</bean>

搜索服务使用休眠搜索,定义如下:

<bean id="supplierSearchService"
        class="com.devcentre.yubi.application.service.SupplierSearchServiceImpl">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

我正在使用spring aop来配置我的事务边界,持久性配置如下:

<tx:annotation-driven transaction-manager="txManager" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                // annotated classes here
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">upgrade</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.provider_class">
                    net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
                <prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider
                </prop>
                <prop key="hibernate.search.default.indexBase">/lucene/indexes</prop>
                <prop key="hibernate.search.default.batch.merge_factor">10</prop>
                <prop key="hibernate.search.default.batch.max_buffered_docs">10</prop>
            </props>
        </property>

    </bean>

    <bean id="txManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

Spring在我的web.xml中配置如下:

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

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

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/src/spring-config.xml 
            /WEB-INF/src/persistence-config.xml 
        </param-value>
    </context-param>

在搜索 JSP 页面上,我有一个表单,它将搜索字符串提交给应该调用 doSearch 方法的操作。但是,当我提交搜索时,出现如下异常(因为启用了 devmode):

Struts has detected an unhandled exception:

Messages:    $Proxy28.doSearch()
File:   java/lang/Class.java Line
number: 1,605

然后是堆栈跟踪:

java.lang.NoSuchMethodException: $Proxy28.addComponent()
    java.lang.Class.getMethod(Class.java:1605)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.getActionMethod(AnnotationValidationInterceptor.java:75)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:47)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)

这很奇怪,因为动作类上有一个带有签名的方法:

public String doSearch()

谁能帮助阐明为什么 ActionProxy 没有预期的方法?

谢谢,

亚历克斯

4

2 回答 2

2

java.lang.NoSuchMethodException: $Proxy25.doSearch()

请注意,您的操作类的名称是$Proxy25。似乎有些东西正在为您的操作类创建动态代理。这通常在对类的方法使用面向方面编程 (AOP) 方法拦截器时出现——例如,对于事务之类的事情。

例如,我不时使用 Google Guice,当在类的方法上使用 AOP 方法拦截器时,调用的操作LoginAction将创建一个名为LoginAction$$EnhancerByGuice$$someAdditionalCharacters. 虽然这个动态代理继承了类的方法,但它不继承注释。我的猜测是这里也发生了同样的事情。

我不使用 Spring,所以我不熟悉它用来创建动态代理的库。

更新

如果您从您的操作类中删除 AOP 注释,那么它应该按预期工作。您的操作类可以委托给服务层类来处理对数据库的持久化(您可以将@Transactional注释放在该类的方法上)。

于 2011-04-30T01:00:38.273 回答
0

struts2 spring & annotation 集成似乎仍然有它的捕获点......

可以使用排除参数来避免从 AnnotationValidationInterceptor 对 getMethod 的第一次调用。

            <interceptor-ref name="validation">
                <param name="excludeMethods">YOURMETHODHERE</param>
            </interceptor-ref>

但是,这只是将问题推迟到由 DefaultActionInvocation 调用的实际方法最终在相同的代码位置 (getMethod Class#1597) 失败,并在代理上使用给定的方法名称。

解决方法

我发现的唯一功能性解决方法是对操作使用标准的 execute() 方法并将操作拆分为不同的类。

希望有帮助。

于 2011-06-15T15:57:38.123 回答