于现代软件开发范畴内,不同系统之间的通信需求广泛存有,然而,运用不同语言所编写的程序如若要达成无缝对话,却是一项长久存在着的技术难题。
Web服务的基本概念
本质上,Web服务是一套标准的解决办法,它能使运行于不同机器上、由不同语言编写的应用彼此通信,这种通信借由通用的网络协议,最常出现的是HTTP或者HTTPS。它着重的优势在于跨国界和跨语言这点上,比如说,一个用Java编写的后台服务,能够轻易地给用Python或者C#开发的客户端供应信息。
是为达成这般互通性,Web服务依靠一连串公开的协议以及标准来阐述本身、传输数据并执行调用。这些标准构建起Web服务的根基,致使开发者不用去操心对方系统的内部实现详情,仅需依照约定好的“接口”展开交互,因而极大程度地提升了系统集成的效率呀灵活性,。
关键的实现协议与规范
在Web服务具体的实现当中,SOAP和REST是两种主流的风格。其中,SOAP也就是简单对象访问协议,它定义了一种严格的、基于XML的消息格式。它把通信内容封装成结构化的、XML的信封,借助HTTP等协议来传输,通常会与WSDL和UDDI等标准相互配合使用,构建起一套企业级服务治理体系。
REST属于一种架构风格,它具备更简单的特性,而且更显灵活。RESTful服务对HTTP协议特性加以直接利用,借助GET、POST等标准方法来对资源予以操作。不同于SOAP强制要求XML的情况,它还能够运用 JSON等具有更轻量特点的数据格式,这致使它在移动应用以及Web前端开发里格外流行,其传输效率也更高 。
Java中的API规范
org.apache.cxf
cxf-rt-frontend-jaxws
3.0.1
org.apache.cxf
cxf-rt-transports-http-jetty
3.0.1
org.slf4j
slf4j-log4j12
1.7.12
junit
junit
4.11
test
Java平台针对这两种风格,提供了官方的API规范,对于基于SOAP的Web服务而言,JAX-WS是核心规范,其API主要处在javax.xml.ws包当中,大量运用注解去简化开发,开发者能够借助注解来定义服务接口,框架会实现SOAP消息的生成与解析的自动处理。
@WebService
public interface HelloWorld {
//对外发布服务的接口的方法
public String sayHello(String name);
}
Java针对 RESTful 服务,给出了 JAX-RS 规范,其 API 处在javax.ws.rs包里面,也是大量运用注解驱动,举例来说,借由@Path去定义资源路径,通过@GET、@POST来指定 HTTP 方法,JAX-RS 规范让服务能够灵活地消费以及生成 XML 或者 JSON 数据,当下主流的实现框架涵盖 Jersey、RESTEasy 等 。
public class HelloWorldImpl implements HelloWorld {
public String sayHello(String name) {
return name+"hello webservice!";
}
}
服务的描述与发现
public class WsTest {
public static void main(String[] args) {
//创建发布服务的工厂
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
//设置服务地址
factory.setAddress("http://localhost:8000/ws/hello");
//设置发布的服务类
factory.setServiceBean(new HelloWorldImpl());
//添加日志输入、输出拦截器,观察soap请求以及soap响应内容
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
//发布服务
factory.create();
System.out.println("发布服务成功,端口8000放行");
}
}
要使得客户端清楚怎样去调用一个Web服务,那就必须对服务予以描述,对于SOAP服务而言,WSDL文件担当了这个角色,WSDL是一份基于XML的文档,它详尽地说明了服务具备哪些方法,方法的参数以及返回值类型是什么,并且服务的网络地址处于哪里 。
于更具宏观性的层面的情形下,UDDI被设计用来构建一个服务注册中心,服务提供商会把其自身的WSDL发布至UDDI注册表,而服务消费者能够在此处去搜索且发现所需的服务,尽管UDDI在企业级服务总线里存在其应用,然而在互联网环境当中,通过URL直接访问WSDL或者API文档是更为常见的做法。
@WebService
public interface HelloWorld {
public String sayHello(String name);
}
使用框架开发服务
Apache CXF是一个颇受欢迎的开源服务框架,它对JAX - WS和JAX - RS这两种开发方式均予以支持。于开发服务端之际,开发者首要需定义一个Java接口,并且运用@WebService等注解把它标记成服务接口 ;框架会依据这一接口生成WSDL,并且处理源自客户端的请求。
public class ClientTest {
public static void main(String[] args) {
//服务接口的访问地址:http://localhost:8000/ws/hello
//创建cxf代理工厂
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
//设置远程访问服务端的地址
factory.setAddress("http://localhost:8000/ws/hello");
//设置接口的类型
factory.setServiceClass(HelloWorld.class);
//对该接口生成代理对象
HelloWorld helloWorld = factory.create(HelloWorld.class);
//打印代理对象类型
System.out.println(helloWorld.getClass());
//远程访问服务端方法
String msg = helloWorld.sayHello("lili");
System.out.println(msg);
}
}
一个关键之处为,需确保远程调用的正确性,服务端接口的完整类名,也就是包名加上接口名,必须要跟客户端所拥有的接口完全相同。另外,要是服务需要传输自定义的 Java 对象,那么这些对象得能够被序列化,而且客户端与服务端的对应类的结构必须维持兼容状态。
org.apache.cxf
cxf-rt-frontend-jaxrs
3.0.1
org.apache.cxf
cxf-rt-transports-http-jetty
3.0.1
org.slf4j
slf4j-log4j12
1.7.12
org.apache.cxf
cxf-rt-rs-client
3.0.1
org.apache.cxf
cxf-rt-rs-extension-providers
3.0.1
org.codehaus.jettison
jettison
1.3.7
junit
junit
4.11
test
org.apache.maven.plugins
maven-compiler-plugin
3.1
1.8
1.8
UTF-8
true
客户端调用与服务消费
服务被客户端调用之际,流程已然十分简化。针对JAX-WS服务而言,客户端能够利用工具生成服务存根,而后如同调用本地方法那般开展远程调用。对于JAX-RS服务来讲,开发者直接借助诸如javax.ws.rs.client.Client这般的客户端API去构建HTTP请求,并且指派出期望返回的数据格式。
#info等级的日志输出到CONSOLE和LOGFILE这两个目的地(LOGFILE表示将日志写到文件中,CONSOLE则将日志写到控制台)
log4j.rootCategory=info,CONSOLE,LOGFILE
#设置日志优先控制台输出
log4j.logger.org.apache.axis.enterprise=FATAL,CONSOLE
#定义控制台日志输出器
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
#控制台日志布局
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
#控制台日志布局的设置
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601}%-6r[.15t]%-5p %30.30c %x-%m\n
#定义文件日志输出器
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
#日志的存放位置
log4j.appender.LOGFILE.File=C:\\All\\jax.log
#启用文件日志追加模式
log4j.appender.LOGFILE.Append=true
#文件日志布局
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
于这些API里头,好多方法调用皆采用了构建者模式,其支持链式编程,这致使代码愈发简洁。比如说,能够接连调用.request()、.accept()以及.get()方法以发送一回请求。调用所返回的响应对象,经由readEntity(Class 。
针对那种要在不一样技术栈中间开展集成的项目,你觉得Web服务往后的发展会更着重于RESTful的简约高效,还是依旧得要SOAP的强规范性以及安全性呢?
xml形式
张三
北京
json形式
{"User":{"name":"张三","city":"北京"}}