使用cxf发布WebService
基础环境:使用SpringBoot框架,Maven构件项目。
第一步:引入所需的Jar包
修改pom.xml,增加需要引入的包。
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.0</version>
</dependency>
第二步:编写配置
新增配置类,代码如下。
@Configuration
public class CxfConfig {
@Bean
public ServletRegistrationBean dispatcherServlet() {
return new ServletRegistrationBean(new CXFServlet(),"/demo/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public TestService demoService() {
return new TestServiceImpl();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), demoService());
endpoint.publish("/api");
return endpoint;
}
}
第三步:定义接口
定义发布的WebService,示例定义了一个有参数的,一个没有参数的,一个返回String,一个返回用户列表。用户只有id,name两属性。
@WebService(name = "TestService", // 暴露服务名称
targetNamespace = "http://webservice.phantom.com"
// 命名空间,一般是接口的包名倒序
)
public interface TestService {
@WebMethod(action = "sayHello")
String sayHello(@WebParam(name = "user" ,targetNamespace = "http://webservice.phantom.com")String user);
@WebMethod(action = "getUsers")
List<User> getUsers();
}
第四步:编写接口实现
编写实现类,实现上述方法,文中只是示例,实现比较简单。
@WebService(serviceName = "TestService", // 与接口中指定的name一致
targetNamespace = "http://webservice.phantom.com",
// 与接口中的命名空间一致,一般是接口的包名倒
endpointInterface = "com.king.phantom.webservice.TestService"// 接口地址
)
public class TestServiceImpl implements TestService {
@Override
public String sayHello( String user) {
return "Hello "+user;
}
@Override
public List<User> getUsers() {
List<User> users = new ArrayList<>();
User u1 = new User();
u1.setId("001");
u1.setName("关羽");
User u2 = new User();
u2.setId("002");
u2.setName("张飞");
users.add(u1);
users.add(u2);
return users;
}
}
至此,咱们的WebService就发布成功了。
注意事项
wsdl地址
WebService发布出去了,就要通过浏览器看看wsdl信息,文中的发布的WebService的wsdl地址是什么呢?是http://127.0.0.1:7000/demo/api?wsdl,注意是demo,不是TestService,这是我手欠在配置类和接口中定义的不同,建议读者设置成相同的,避免后期维护引起不必要的麻烦。
返回对象List的数据格式
文中getUsers方法会返回一个对象列表,返回的数据如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getUsersResponse xmlns:ns2="http://webservice.phantom.com">
<return>
<id>001</id>
<name>关羽</name>
</return>
<return>
<id>002</id>
<name>张飞</name>
</return>
</ns2:getUsersResponse>
</soap:Body>
</soap:Envelope>
数据格式和以往开放的WebService不同,为了方便cxf客户端读取方便,此处直接返回的是多个对象,cxf客户端可以直接获取对象列表,但是直接解析Xml,需要做特殊处理,建议如果发布通用WebService还是套一层壳。
"意外的元素 (uri:“http://webservice.phantom.com“, local:“arg0“)。所需元素为<{}arg0>"问题处理
看代码示例大家会看到接口中sayHello方法是有一个参数的,参数加了WebParam注解,定义了name和WebParam值,这个很重要,如果没有这两个配置,客户端调用时会报错,错误信息如下:
意外的元素 (uri:"http://webservice.phantom.com", local:"arg0")。所需元素为<{}arg0>
加了注解,调用时参数名使用name定义的名称就不会报错了。