尊敬的 Stackoverflow 用户您好,最近我一直在为带有 Spring 框架的轴 2 Web 服务的一个特定问题而苦恼。我已经阅读了许多不同的指南并阅读了不同的论坛,但发现人们遇到了同样的问题但没有解决方案。基本上最后我用双手握住显示器并大喊“你发现了什么 BudapestHacker938?”。无论如何,我的axis2 Web服务类需要Spring bean,因此它们在Web服务类中自动装配。在我拥有 servletContext 的码头服务器中,一切都运行良好。只需在 web.xml 中定义所需的侦听器即可。这样的幸福。但不幸的是,所有好事都会在某个时候结束,对我来说,魔鬼是大型机内部的 CICS 环境。没有像 Jetty/Tomcat 那样的 servletcontext,幸运的是它仍然支持axis2。因此,根据不同的用户指南,我决定将我的网络服务存档到 .aar 中,并将其添加到 services 文件夹下。Axis2文件夹结构如下:
- 存储库/
- 模块
- 服务
当我构建这个 .aar 存档时,我也在生成自己的 wsdl,而不是使用axis2内置的wsdl生成器,它根据services.xml从给定的类中生成服务(当我运行axis2server时,不使用因为没有'据我所知,不喜欢 JAX-WS 注释)。为了初始化 Spring 框架,我需要编写一个小的 SpringInit 类来初始化 Spring bean。不幸的是,它也出于某种原因根据其注释初始化了我的 Web 服务类,然后占用了主端口(怀疑 SpringInit 自己初始化 Web 服务类,因为它也被定义为 Spring bean 并且 SpringInit 扩展了 Axis2 类 ServiceLifeCycle)我得到 JVM BIND 异常,它表明该地址已在使用中。我想根据存储在 WSDL 内部的 wsdl 建立服务,而不是生成新的服务,因为我有各种环境:1)本地机器 - 码头 2)大型机。无论如何,我对我的 services.xml 进行了深入了解:
<service name="Absence" class="org.services.SpringInit">
<description>
random description
</description>
<parameter name="ServiceTCCL">composite</parameter>
<parameter name="useOriginalwsdl" locked="false">true</parameter>
<parameter name="ServiceObjectSupplier">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
<parameter name="ServiceClass">org.services.Absence</parameter>
<parameter name="SpringBeanName">absence</parameter>
<parameter name="SpringContextLocation">META-INF/applicationContextAar.xml</parameter>
</service>
Spring applicationContextAar.xml,为亲爱的 Stack 社区做了一点重构:
<beans>
<bean id="applicationContext" class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:tcp://localhost/~/devDb" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="absence" class="org.services.Absence"></bean>
<bean id="jtemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="ds"></constructor-arg>
</bean>
<bean id="datasetFactory" class="org.vsam.DataSetFactory"></bean>
<bean id="dataManagerFactory" class="org.datamanager.DataManagerFactory"></bean>
<bean id="absenceFactory" class="org.services.AbsenceFactory"></bean>
<bean id="h2Database" class="org.dataset.H2Database"><constructor-arg ref="jtemplate"></constructor-arg>
</bean>
<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"></bean>
</beans>
我的 SpringInit 类看起来像这样:
public class SpringInit implements ServiceLifeCycle {
public void startUp(ConfigurationContext ignore, AxisService service) {
try {
ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext appCtx = new
ClassPathXmlApplicationContext(new String[] {"applicationContextAar.xml"}, false);
appCtx.setClassLoader(classLoader);
appCtx.refresh();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void shutDown(ConfigurationContext ctxIgnore, AxisService ignore) {}
}
现在我们转到 org.services.Absence.class,它是一个普通的 JAX-WS Web 服务类,具有以下标头(包含 JAX-WS 注释):
@WebService(name = "AbsenceService", serviceName = "Absence", portName = "Absence",
targetNamespace = "http://www.something.org/Absence")
public class Absence extends ServiceHandlerBase {
@Autowired
private AbsenceFactory absenceFactory;
@Autowired
private DataManagerFactory dataManagerFactory;
@Autowired
private DataSetFactory dataSetFactory;
...
}
包含这样的方法:
@WebMethod
@WebResult(name = "AbsenceResponse")
public SearchAbsenceRecordsResponse invokeSearchAbsenceRecords(
@WebParam ServiceRequest request,
@WebParam SearchAbsenceRecordsRequest absenceRequest) {...}
一种替代方法是将“servicejars”文件夹添加到“repository”文件夹中,并使用absence.jar 填充它,该jar 的所有依赖项都位于子文件夹“lib”中。Axis2 然后自动运行 absense.jar,因为它具有 JAX-WS 注释。但是在那里,当我使用 SOAP-UI 调用 Web 服务时,它没有初始化 Spring,因为我不知道如何在该解决方案中初始化 Spring。也许有人对此有任何专长。
TL;博士
如何让我的 Spring bean 初始化为它不会根据注释启动 Web 服务类中的服务,而是根据 wsdl 构建服务?
欢迎您提出问题。