WebService是一种跨编程语言、跨操作系统平台的远程调用技术,广泛应用在实际开发,接口实现,系统集成。
服务端
List item
添加maven依赖
项目中除了spring相关的依赖以外,还需添加下面两个依赖。
<dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.3.5</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.3.5</version><scope>compile</scope></dependency>
配置web.xml
除了常规的spring相关配置,这里需要添加cxfServlet的配置。
<!-- 1.cxfServlet配置--><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>/webservice/*</url-pattern></servlet-mapping><!-- 2.配置spring容器--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value><!-- 3.监听器--></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
编写webService接口以及实现类
IHelloService 接口类
接口需要标注@webservice注解
@WebServicepublic interface IHelloService {/***对外发布服务接口的方法*@param name*/public String welcome(String name);}
HelloServiceImpl 接口实现类
public class HelloServiceImpl implements IHelloService {@Overridepublic String welcome(String name) {return "welcome to webService "+name;}}
配置applicationContext.xml
在命名空间中需要添加cxf相关的xsd,然后配置服务对应的信息,包括服务地址,服务类等
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:jaxws="/jaxws" xmlns:cxf="/jaxws"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd/schema/context/schema/context/spring-context-3.0.xsd/jaxws/schemas/jaxws.xsd"><cxf:server address="/hello"><jaxws:serviceBean><bean class="service.impl.HelloServiceImpl"></bean></jaxws:serviceBean></cxf:server></beans>
启动web服务,测试
服务启动成功后,我们可以在浏览器中访问:http://localhost:8081/webservice/hello?wsdl
其中,http://localhost:8081
为我们服务器访问入口,/webservice
为我们在web.xml
配置文件中配置的cxfServlet
对应的servlet-mapping
,/hello
为该服务访问的address
地址,最后还需要加上?wsdl
访问wsdl说明书。
下图为ie浏览器的显示效果,我测试的火狐浏览器则显示空白,对应f12的内容与下图内容一致。
客户端
添加cxf相关依赖
导入服务接口类型对应的类
这里,我们需要将服务端的IHelloService和HelloServiceImpl添加到客户端代码中。另外,不管是客户端还是服务端,IHelloService接口都是需要标注@webService注解的。
编写客户端的applicationContext.xml
服务端定义了接口服务类型,服务地址,与之对应地,客户端同样需要配置服务地址,服务接口类型。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:jaxws="/jaxws" xmlns:cxf="/jaxws"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd/schema/context/schema/context/spring-context-3.0.xsd/jaxws/schemas/jaxws.xsd"<jaxws:client id="helloService" serviceClass="service.impl.HelloServiceImpl" address="http://localhost:8081/webservice/hello"></jaxws:client></beans>
编写单元测试
这里使用到了spring的单元测试,所以,不光要导入junit
的依赖,还需要spring-test
的依赖。
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Client {//注入对象@Resourceprivate HelloServiceImpl helloService;@Testpublic void doClientRemote(){System.out.println(helloService);String content = helloService.welcome("Elaine");System.out.println(content);}}
查看输出结果
org.apache.cxf.jaxws.JaxWsClientProxy@45905bffwelcome to webService Elaine
可以发现,我们获取的HelloServiceImpl 对象是代理对象,因为事先了相关接口,自然是通过jdk动态代理实现的。
查看服务端输出时,有这样一个警告
org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://impl.service/}welcome found. Expected {http://service/}welcome.
很好理解,我们在单元测试获取的代理对象类型为实现类,cxf更希望我们直接用接口类型。替换为:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Client {//注入对象@Resourceprivate IHelloService helloService;@Testpublic void doClientRemote(){System.out.println(helloService);String content = helloService.welcome("Elaine");System.out.println(content);}}
重新测试,无警告,无报错。