要把项目里的业务层,用 WebService 有选择的发布出来.
碰到调用 WebService 发布的服务时,业务层中 Spring 注入的 Bean 都为空的情况.(用JUnit调用服务是正常的)
好是一顿折腾,这个问题很普遍,不知道为什么网上好的解答并不多,所以把解决过程和大家分享.
问题分析, 业务层 Bean 使用的 Spring 容器和调用 WebService 服务中使用的不是同一个 Spring 容器.
所以,在 WebService 中获得不到已经注入的业务 Bean.
为了解决这个问题,先后用到 Axis1,Axis2 和 xfire.
最后经过徐培成(授业恩师)的指导,发现最新发布的 CXF(xfire改后的名), 解决这个问题很干脆.
1. apache-cxf-2.4.1 需要导入的包. 和其他框架集成的时候,注意去掉同名的包.
commons-logging-1.1.1.jar
cxf-2.4.1.jar
geronimo-activation_1.1_spec-1.1.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.7.1.jar
geronimo-servlet_3.0_spec-1.0.jar
geronimo-ws-metadata_2.0_spec-1.1.3.jar
jaxb-api-2.2.1.jar
jaxb-impl-2.2.1.1.jar
jaxb-xjc-2.2.1.1.jar
jetty-server-7.4.2.v20110526.jar
jetty-util-7.4.2.v20110526.jar
neethi-3.0.0.jar
saaj-api-1.3.jar
saaj-impl-1.3.2.jar
wsdl4j-1.6.2.jar
wss4j-1.6.1.jar
xmlbeans-2.4.0.jar
xmlschema-core-2.0.jar
2. web.xml
<!-- WebService.CXF -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
注意:这里要是用到了 struts 等,要看一下过滤器或 servlet.
3. 在 Spring 的配置文件中配置. 这个是解决问题的关键.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="grupCustService" class="com.test.service.impl.GrupCustService"/>
<jaxws:endpoint id="grupCustServiceweb" address="/GrupCustServiceWeb"
implementorClass="com.test.service.impl.GrupCustService">
<jaxws:implementor ref="grupCustService"/>
</jaxws:endpoint>
</beans>
解决 Spring 注入 Bean 为空的情况,这个文件的配置是关键.
<jaxws:implementor ref="grupCustService"/>中, grupCustService 是需要发布的实现类,在 Spring 容器中注入的名.
只有加上这句, 就可以很顺利的获得业务 Bean.
4. Java 类
接口类
@WebService (必须要有)
public interface HelloWorld {
String sayHello(@WebParam(name="text") String text);
}
实现类
括号里的参数可以不写,这个和自动生成的客户端的包有关系,建议写上.
@WebService(endpointInterface = "com.test.service.HelloWorld", serviceName = "HelloWorld")
public class HelloWorldImpl implements HelloWorld {
public String sayHello(String text) {
return "Hello " + text;
}
}
5. 获得 wsdl
在 IE 中访问 http://localhost:8080/项目名/services/GrupCustServiceWeb?wsdl