0

使用する jar の詳細: 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>

最初のアクションはユーザーを検索ページに送り、ユーザーは検索文字列を入力し、フォームを投稿すると 2 番目のアクションが呼び出されます。

spring config でのアクションは次のとおりです。

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

検索サービスは hibernate 検索を使用し、次のように定義されます。

<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であることに注意してください。何かがアクション クラスへの動的プロキシを作成しているようです。これは通常、クラスのメソッドで Aspect Oriented Programming (AOP) メソッド インターセプターを使用する場合に見られます。たとえば、トランザクションなどです。

たとえば、私はときどき Google Guice を使用します。クラスのメソッドで AOP メソッド インターセプターを使用する場合、呼び出されたアクションLoginActionには という動的プロキシが作成されLoginAction$$EnhancerByGuice$$someAdditionalCharactersます。この動的プロキシはクラスのメソッドをサブクラス化しますが、アノテーションは継承しません。私の推測では、ここでも同じことが起こっています。

私は Spring を使用していないため、動的プロキシを作成するために使用するライブラリについてよく知りません。

アップデート

アクション クラスから AOP アノテーションを削除すると、期待どおりに動作するはずです。アクション クラスはサービス層クラスに委譲して、データベースへの永続化を処理できます (@Transactionalそのクラスのメソッドに注釈を付けることができます)。

于 2011-04-30T01:00:38.273 に答える
0

struts2 のスプリングとアノテーションの統合にはまだ問題があるようです...

AnnotationValidationInterceptor からの getMethod への最初の呼び出しは、除外パラメーターを使用して回避できます。

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

ただし、これは実際のメソッドが DefaultActionInvocation によって呼び出されて同じコードの場所 (getMethod Class#1597) で呼び出されるまで問題を延期するだけであり、プロキシで指定されたメソッド名で失敗します。

回避策

私が見つけた唯一の機能的な回避策は、アクションに標準の execute() メソッドを使用し、アクションを異なるクラスに分割することでした。

それが役立つことを願っています。

于 2011-06-15T15:57:38.123 に答える