使用的罐子的详细信息: 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>
搜索服务使用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没有预期的方法?
谢谢,
亚历
答案 0 :(得分:1)
java.lang.NoSuchMethodException: $Proxy25.doSearch()
请注意,您的操作类的名称是 $ Proxy25 。似乎有些事情正在为您的动作类创建动态代理。当在类的方法上使用面向方面编程(AOP)方法拦截器时通常会出现这种情况 - 例如,对于像事务这样的事情。
例如,我不时使用Google Guice,当在类的方法上使用AOP方法拦截器时,名为LoginAction
的操作会创建一个名为LoginAction$$EnhancerByGuice$$someAdditionalCharacters
的动态代理。 虽然这个动态代理子类是类的方法的子类,但它不会继承注释。我猜这里发生了同样的事情。
我不使用Spring,所以我不熟悉它用来创建动态代理的库。
<强>更新强>
如果从动作类中删除AOP注释,则它应该按预期工作。您的操作类可以委托给服务层类来处理持久化到数据库(您可以在该类的方法上放置@Transactional
注释)。
答案 1 :(得分:0)
struts2弹簧&amp;注释整合似乎仍有其捕获......
使用排除参数可以避免从AnnotationValidationInterceptor中第一次调用getMethod。
<interceptor-ref name="validation">
<param name="excludeMethods">YOURMETHODHERE</param>
</interceptor-ref>
然而,这只是推迟了问题,直到DefaultActionInvocation调用实际方法结束于相同的代码位置(getMethod类#1597),该代码位置在代理上使用给定的方法名称失败。
替代方法
我发现的唯一功能性解决方法是对操作使用标准的execute()方法,并将操作拆分为不同的类。
希望有所帮助。