简单地说WebService就是一种Web服务,他是一种跨编程语言和操作系统的远程调用技术。WebService的传输依赖于HTTP协议,通过SOAP协议使用XML格式进行数据传输。
WebService的三要素如下:
下面直接给出一个WebService的具体实例来说明原生态的WebService开发
具体代码如下:
@WebService
public interface HelloService {
@WebMethod
String sayHello(String name);
}
@WebService // 实现类必须要添加@WebService注解
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "你好:" + name;
}
}
以上我们定义了需要发布的接口,接下来就是将接口发布到注册中心使其成为WebService服务。具体代码如下:
public class WebServicePublisher {
public static void main(String[] args) {
// STEP1: 定义服务发布的地址
String address = "http://localhost:9999/WS/HelloService";
// STEP2: 发布WebService服务
Endpoint.publish(address, new HelloServiceImpl()); // 第一个参数表示发布到注册中心的地址 第二个参数表示当有客户端向该地址发送请求的时候,服务器端对应的处理类
// STEP3: 打印发布服务成功信息
System.out.println("HelloService发布成功!");
}
}
服务发布成功之后,我们直接在浏览器输入:http://localhost:9999/WS/HelloService?wsdl即可获取注册中心的WSDL文件:
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://server.webservice.rampage.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://server.webservice.rampage.com/" name="HelloServiceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://server.webservice.rampage.com/" schemaLocation="http://localhost:9999/WS/HelloService?xsd=1"/>
</xsd:schema>
</types>
<message name="sayHello">
<part name="parameters" element="tns:sayHello"/>
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse"/>
</message>
<portType name="HelloServiceImpl">
<operation name="sayHello">
<input message="tns:sayHello"/>
<output message="tns:sayHelloResponse"/>
</operation>
</portType>
<binding name="HelloServiceImplPortBinding" type="tns:HelloServiceImpl">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="sayHello">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="HelloServiceImplService">
<port name="HelloServiceImplPort" binding="tns:HelloServiceImplPortBinding">
<soap:address location="http://localhost:9999/WS/HelloService"/>
</port>
</service>
</definitions>
WSDL文档的相关说明如下:
我们有两种方式可以生成客户端代码
1. 如果服务端已经启动,我们可以在CMD中使用wsimport命令来自动生成代码:
wsimport -s E:\workspacce\myWebServiceClient\src -keep http://localhost:9999/WS/HelloService?wsdl
其中-s参数指定的是生成的源码路径,这里我指定客户端代码路径(不需要指定到具体包路径,生成代码的时候会自动生成到与服务器端的同路径文件夹下)。最终生成的文件结构如下:
此时我们写的客户端测试代码为:
public static void main(String[] args) {
// STEP1: 实例化WebService工厂
HelloServiceImplService serviceFactory = new HelloServiceImplService();
// STEP2: 得到远程的Service实例
HelloServiceImpl serviceImpl = serviceFactory.getHelloServiceImplPort();
// STEP3: 远程调用WebService方法
System.out.println(serviceImpl.sayHello("KiDe"));
}
我们写的客户端测试代码为:
public class WebServiceInvoker {
public static void main(String[] args) throws ServiceException, RemoteException {
/**
* Method1: 通过HelloServiceImplServiceLocator来获取远程接口
*/
/*// STEP1: 实例化WebService工厂
HelloServiceImplService serviceFactory = new HelloServiceImplServiceLocator();
// STEP2: 得到远程的Service实例
HelloServiceImpl serviceImpl = serviceFactory.getHelloServiceImplPort();
// STEP3: 远程调用WebService方法
System.out.println(serviceImpl.sayHello("KiDe"));*/
/**
* Method2: 通过代理类来获取远程接口
*/
// STEP1: 实例化WebService工厂
HelloServiceImplProxy serviceProxy = new HelloServiceImplProxy();
// STEP2: 得到远程的Service实例
HelloServiceImpl serviceImpl = serviceProxy.getHelloServiceImpl();
// STEP3: 远程调用WebService方法
System.out.println(serviceImpl.sayHello("KiDe"));
// System.out.println(serviceProxy.sayHello("KiDe")); // 也可以直接通过代理类调用服务
}
}
同理我们也可以通过指定远程接口实现类的方式自动生成服务端代码。其实通过eclipse创建客户端或者服务端的方式是使用了CXF框架。会发现此时WSDL生成的测试类调用远程WebService服务相当慢,并且在运行的时候会出现如下警告:
警告: Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart). Attachment support is disabled.
网上搜索发现时因为少了activation.jar和mail.jar,将这两个jar添加进入项目的build path之后发现告警消除,但是执行还是耗时很长。这说明CXF框架虽然简化了开发,但是执行效率大打折扣。
百科上关于CXF的解释如下:
Apache CXF是开源的,CXF是两个项目的结合:由IONA技术公司(现在是Progress的一部分)开发的Celtix和由Codehaus主持的团队开发的XFire,合并是由人们在Apache软件基金会共同完成的。CXF的名字来源于"Celtix"和"XFire"的首字母
官网上的说明如下:
Apache CXF™ is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.
直接去官网http://cxf.apache.org/下载,这里我下载的版本为: 3.2.1。解压之后文件目录结构如下:
具体目录说明如下:
直接新建一个Java项目,然后将CXF的lib目录下的所有jar包添加到项目的build path。
直接上代码:
@WebService
@BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface HelloService {
String sayHello(String name);
}
@WebService
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "你好:" + name;
}
}
public class ServicePublisher {
public static void main(String[] args) {
// STEP1: 创建Bean工厂
JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
// STEP2: 设置服务发布地址已经发布的接口
factoryBean.setAddress("http://localhost:8888/ws/HelloService");
factoryBean.setServiceClass(HelloService.class);
factoryBean.setServiceBean(new HelloServiceImpl());
// STEP3: 发布服务
factoryBean.create();
System.out.println("HelloService服务发布成功!");
}
}
需注意这里需用到JDK1.8
在CXF工具的bin目录下执行下面命令:
wsdl2java –d . http://localhost:8888/ws/HelloService?wsdl
会在bin目录下生成对应客户端代码,代码与直接通过wsimport一致
与前面一致,这里不再说明
实现一个完整的WebService服务包括以下步骤:
◆ Web服务提供者设计实现Web服务,并将调试正确后的Web服务通过Web服务中介者发布,并在UDDI注册中心注册(发布) ◆ Web服务请求者向Web服务中介者请求特定的服务,中介者根据请求查询UDDI注册中心,为请求者寻找满足请求的服务(发现) ◆ Web服务中介者向Web服务请求者返回满足条件的Web服务描述信息,该描述信息用WSDL写成,各种支持Web服务的机器都能阅读(发现) ◆ 利用从Web服务中介者返回的描述信息生成相应的SOAP消息,发送给Web服务提供者,以实现Web服务的调用(绑定) ◆ Web服务提供者按SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者(绑定)
xml <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping>
xml <jaxws:server id="bye" address="/bye" serviceClass="com.rl.cxf.web.inter.ByeInter"> <jaxws:serviceBean> <bean class="com.rl.cxf.web.inter.ByeInterImpl"></bean> </jaxws:serviceBean> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean> </jaxws:outInterceptors> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean> </jaxws:inInterceptors> </jaxws:server>
一般来说如果web项目想集成CXF框架来进行WebService调用,至少需要引入CXF相关的jaxws和http协议的支持
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.2.1</version>
</dependency>
http://blog.csdn.net/jiandanfeng2/article/details/53439748 http://blog.csdn.net/qq_14852397/article/details/52761425 http://blog.csdn.net/aqsunkai/article/details/51711087 http://blog.csdn.net/qq32933432/article/details/51394749 http://blog.csdn.net/qq_35712358/article/details/71244342 https://www.cnblogs.com/fengwenzhee/p/6915606.html http://blog.csdn.net/yangwenxue_admin/article/details/51059125
与Spring框架集成请看后续更新的Spring官方文档解读之远程调用和WebService篇