鲁春利的工作笔记,谁说程序员不能有文艺范?
基本概念参阅:http://www.w3school.com.cn/ws.asp
Web Service可以认为是一种标准,定义了操作的规范,任何语言都可以发布自己的服务或者实现自己的client来使用其他厂商提供的服务,数据交换的过程则是透明的。
不同的平台,不同的语言大都提供Web Service的开发实现,在JAVA领域,Web Service的框架很多,例如:Axis1&2,Xfire,CXF,Java自带的JAX-WS。
1、JAX-WS
JAX-WS(Java API For XML-WebService),JDK1.6 自带的版本为JAX-WS2.1,其底层支持为JAXB(Java Architecture for XML Binding)。
JAX-WS(JSR 224)规范的API 位于javax.xml.ws.*包,其中大部分都是注解,提供API 操作Web 服务(通常在客户端使用的较多,由于客户端可以借助SDK 生成,因此这个包中的API 我们较少会直接使用)。
WS-MetaData(JSR 181)是JAX-WS 的依赖规范,其API 位于javax.jws.*包,使用注解配置公开的Web 服务的相关信息和配置 SOAP 消息的相关信息。
2、Axis2
(Apache eXtensibleInteraction System)是Apache下的一个重量级WebService框架,提供了多语言支持。
3、XFire
XFire在2007年后已停止更新,最后的一个版本是1.2.6,在2007年5月3日发布。正式更名为Apache CXF,亦可以说是XFire2.0。
4、Apache CXF
Apache CXF是开源的,是Celtix和XFire合并发展而来,CXF的名字来源于"Celtix"和"XFire"的首字母。
CXF不仅提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,以及可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。
Web Service接口
package com.lucl.apps.web.webservice.cxf.server; import javax.jws.WebService; // 不指定名称的时候默认是实现类+分类(如Service、Port、PortType) @WebService(name="HelloWorldPortType") public interface HelloWorld { String sayHi(String text); }
接口声明后使用类级别注解@WebService就标注了这个接口的方式将公开为Web服务,如果希望屏蔽掉某个方法,可以使用方法注解@Method的exclude=true。通常把公开为Web服务的接口叫做SEI(Service EndPoint Interface)服务端点接口。
实现类HelloWorldImpl
package com.lucl.apps.web.webservice.cxf.server; /** * @author lucl * @description 将serviceNmae标注到HelloWorld接口查看wsdl文件时service仍然为实现类+Service */ @WebService(serviceName="HelloWorld", portName="HelloWorldPort") public class HelloWorldImpl implements HelloWorld { @Override public String sayHi(String text) { System.out.println("sayHi called"); return "Hello " + text; } }
这个实现类没有任何特殊之处,但是如果你的实现类还实现了其他的接口,那么你需要在实
现类上使用@WebService 注解的endpointInterface 属性指定那个接口是SEI(全类名)。Web服务的实现类通常称为SIB (Service Implementation Bean)。
注意:JDK API说明在接口上不能指定endpointInterface属性,测试发现client调用访问时会出错。
发布服务
package com.lucl.apps.web.webservice.cxf.server; import javax.xml.ws.Endpoint; import org.apache.cxf.endpoint.Server; import org.apache.cxf.jaxws.JaxWsServerfactorybean; /** * * @author luchunli * @description 自定义Web Service的Server * */ public class WebServiceServer { public static void main(String args[]) { // CXF实现方式 // { // JaxWsServerfactorybean factory = new JaxWsServerfactorybean(); // factory.setServiceClass(HelloWorldImpl.class); // factory.setAddress("http://localhost:9000/helloWorld"); // Server server = factory.create(); // server.start(); // // System.out.println("Server ready..."); // // try { // Thread.sleep(5 * 60 * 1000); // } catch (InterruptedException e) { // e.printstacktrace(); // } // System.out.println("Server exiting"); // System.exit(0); // } // JAX-WS实现方式 HelloWorldImpl implementor = new HelloWorldImpl(); String address = "http://localhost:9000/helloWorld"; Endpoint.publish(address, implementor); System.out.println("Server ready..."); } }
使用javax.xml.ws包中的EndPoint类的静态方法publish来发布服务。
public abstract class Endpoint extends Object
JDK API 1.6中对javax.xml.ws.Endpoint说明如下:
JAX-WS 2.0引入的类,称为Web 服务端点。 使用在此类中定义的静态方法创建端点。一个端点总是绑定到一个 Binding 和一个实现者, 这两项都是在创建端点时设置的。 端点要么处于已发布状态,要么处于未发布状态。可以使用 publish 方法开始发布端点,此时端 点开始接受传入请求。相反,可以使用 stop 方法停止接受传入请求并取消端点。一旦停止,就不能再 次发布该端点。 可以在端点上设置 Executor 以便更好地控制用来指派传入请求的线程。例如,通过创建 ThreadPoolExecutor 并向端点注册可以启用带有特定参数的线程池。 处理程序链可以使用所含的 Binding 来设置,Binding 接口是 JAX-WS 协议绑定的基本接口。 端点可以使一个元数据文档(如 WSDL 和 XMLSchema 文档)列表与之绑定。发布时,JAX-WS 实现 将根据实现者上存在的注释,尽可能多地重用这些元数据,而不是生成新的元数据。
运行WebServiceServer类
查看WSDL
实现客户端
package com.lucl.apps.web.webservice.cxf.client; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; import com.lucl.apps.web.webservice.cxf.server.HelloWorld; import org.apache.cxf.jaxws.JaxWsProxyfactorybean; /** * * @author luchunli * @description 自定义Web Service的Client * */ public final class WebServiceClient { private WebServiceClient() { // ...... } public static void main(String args[]) throws Exception { // cxf实现 // { // JaxWsProxyfactorybean factory = new JaxWsProxyfactorybean(); // factory.setServiceClass(HelloWorld.class); // factory.setAddress("http://localhost:9000/helloWorld"); // HelloWorld helloworld = (HelloWorld) factory.create(); // System.out.println(helloworld.sayHi("luchunli")); // System.exit(0); // } // wsdl文档路径 URL wsdlDocument = new URL("http://localhost:9000/helloWorld?wsdl"); // QName参数为指定名称空间 URI 和本地部分的 QName 构造方法。 // URI实际就是把包名给倒过来了 // 而nativeQName默认为实现类+Service,通过serviceName指定名称。 String namespaceURI = "http://server.cxf.webservice.web.apps.lucl.com/"; String nativeQName = "HelloWorld"; // 对应wsdl:service QName qname = new QName(namespaceURI, nativeQName); // Service 对象提供 Web 服务的客户端视图。 Service service = Service.create(wsdlDocument, qname); // Class<HelloWorld> serviceEndpointInterface = HelloWorld.class; HelloWorld helloWorld = service.getPort(serviceEndpointInterface); System.out.println(helloWorld.sayHi("luchunli")); } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。