WebService开源框架的选择
目前主流的Web Service框架主要有3种: Axis 2, CXF, 和 Spring WS。其中Spring WS出身Spring框架,名门出身,听说比较难用。Axis 2和CXF都是来自于Apache, 各个方面相差不多,但是考虑到目前市场上使用CXF比较多一点,就才用了CXF。
1.在POM.xml中添加正确的依赖包。
<cxf.version>2.7.14</cxf.version>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
2.创建服务接口
package shzj.web.webService.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface CxfDemo {
@WebMethod
String helloWord(@WebParam(name = "userName") String arg);
}
注意:“@WebService”标记表示该接口是一个WebService服务;“@WebMethod”表示表示以下方法为WebService服务中的方法;“@WebParam(name="username")”表示方法中的参数,username属性限制了参数的名称,若没有指定该属性,参数将被重命名。
3.服务实现类
package shzj.web.webService.service.imple;
import shzj.web.webService.service.CxfDemo;
public class CxfDemoImple implements CxfDemo {
public String helloWord(String arg) {
return "hello "+arg+"!!!";
}
}
4.在Web.xml中声明CXF监听器
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
5.创建WebService声明的Spring配置文件spring-cxf-service.xml
<?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-servlet.xml"/>
<bean id="cxfDemoImple" class="shzj.web.webService.service.imple.CxfDemoImple"/>
<jaxws:endpoint id="hello" implementor="#cxfDemoImple" address="/helloWorld" />
</beans>
spring-cxf-service.xml必须要被spring容器扫描到。
6.测试Web Service
http://127.0.0.1:8080/shzj/webservice/helloWorld?wsdl
webService发布成功
创建CXF客户端进行测试
在客户端生成本地服务类,可以使用"wsdl2java.bat"的工具,也可以利用Java自带的方式生成WS客户端文件。这里我们使用Java自带的wsimport命令。
C:\Users\Administrator>wsimport -d c:/ -keep -encoding utf-8 -p com.demo.client
http://127.0.0.1:8080/shzj/webservice/helloWorld?wsdl
-d <directory> 指定放置生成的输出文件的位置
-encoding <encoding> 指定源文件所使用的字符编码
-keep 保留生成的文件
-p <pkg> 指定目标程序包
将生成的Java文件拷贝到 com.demo.client 包下。
编写客户端测试类,模拟调用服务
第一种实现方式:通过JaxWsProxyFactoryBean代理类来设定服务处理类和服务地址,无须额外的客户端配置。
@Test
public void text1() {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(CxfDemo.class);
factory.setAddress("http://127.0.0.1:8080/shzj/webservice/helloWorld?wsdl");
CxfDemo client = (CxfDemo) factory.create();
String response = client.helloWord("小花");
System.out.println("返回: " + response);
}
结果:
返回: hello 小花!!!
注意:此种方式比较方便,无须配置比较灵活,大部分情况下都会采用这种方式调用服务程序。
第二种实现方式:通过配置客户端来调用服务,方式比较麻烦需要额外对客户端进行配置。
声明的Spring配置文件spring-cxf-client.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd"
>
<bean id="client" class="com.demo.client.CxfDemo"
factory-bean="clientFactory" factory-method="create"/>
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="com.demo.client.CxfDemo"/>
<property name="address"
value="http://localhost:8080/shzj/webservice/helloWorld"/>
</bean>
</beans>
@Test
public void text2() {
ApplicationContext factory = new ClassPathXmlApplicationContext("/spring-cxf-client.xml");
CxfDemo client = (CxfDemo)factory.getBean("client");
String response = client.helloWord("小米");
System.out.println("返回: " + response);
}
结果:
返回: hello 小米!!!
实际上这种方式与第一种方式在过程上是一致的,都是设定服务处理类和WDSL地址的过程,只不过方式不一样。可以根据项目的不同设计而进行选择!