WebService(异构系统之间的互调)
什么是Webservice
是一种服务导向的技术,通过标准的Web协议提供服务,目的是保证不同的平台的应用服务可以操作
从表面上看,webService 就是一个应用程序,向外界暴露出一个可以通过Web进行调用的方法的API,能用编程的方法通过Web调用来实现某个功能的应用程序
就是说,对于不同平台之间WebService其实就是相当于微服务架构中Nacos 的作用,将必要的接口暴露出来,提供给其他平台使用,WebService 就是将平台中的一些接口暴露出来,提供给其他的平台做调用
WebService 核心组件
- XML 和 HTTP
- SOAP:简单对象访问协议
- WSDL:WebService描述语言
- UDDI:同意描述、发现和集成协议
WebService 的主流框架
-
XFire
-
Axis1 Axis2
(Apache eXtensible Interaction System) 阿帕奇可扩展交互系统
开源的WebService 引擎,本质上就是一个SOAP引擎,提供创建服务器端、客户端和网关SOAP操作的基本框架
Axis分为1.x系列和2系列,两个系列体系结构和使用上有较大的区别,相对而言Axis1.x更加稳定,文档也比较齐全 http://axis.apache.org
-
CXF (Celtix + Xfire)
提供了对JAX-WS全面支持,并且提供了多种Bingding,DataBinding、Transport 以及各种Format 的支持,并且可以根据实际项目的需要,采用代码优先,或者WSDL优先,来轻松的实现WebService 的发布和使用 http://cxf.apache.org
// 开启创建一个服务端
package com.zhibin.cfx;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class MainServer {
public static void main(String[] args) {
// 创建一个服务端对象
JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
jaxWsServerFactoryBean.setAddress("http://localhost:8101/WebServiceLearnt");
jaxWsServerFactoryBean.setServiceClass(HelloImpl.class);
// 常见一个服务器
Server server = jaxWsServerFactoryBean.create();
server.start();
}
}
//接口
package com.zhibin.cfx;
import javax.jws.WebService;
@WebService
public interface hello {
public String sayHello(String name,int age);
}
//接口实现类
package com.zhibin.cfx;
import javax.jws.WebParam;
public class HelloImpl implements hello {
@Override
public String sayHello(@WebParam String name,@WebParam int age) {
// TODO Auto-generated method stub
return "hello "+name+"this is cfx"+"and you are "+age;
}
}
// jetty
// 客户端调用接口
package com.zhibin.cfx;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.sun.xml.xsom.parser.JAXPParser;
public class Client {
public static void main(String[] args) {
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setAddress("http://localhost:8011/WebServiceLearnt");
jaxWsProxyFactoryBean.setServiceClass(hello.class);
hello hlo = (hello) jaxWsProxyFactoryBean.create();
String result = hlo.sayHello("caozhibin", 25);
System.out.println(result);
}
}
WSDL文件解析
首先一个WSDL 的标配
-
xmlns:ns1=“http://schemas.xmlsoap.org/soap/http” 相当于Java 里面的import
-
name="HelloImplService name Java 当中的服务接口实现 类SEI定义是服务接口类+Service 后缀Service 自动追加
-
targetNamespace=“http://cfx.zhibin.com/” 命名空间
-
<wdsl:definitions 为根元素
-
<wsdl:type webserivce 使用的数据
-
<wsdl:message webservice 使用的消息 每个方法对应两个message ,一个对应输入一个对应输出
-
<wsdl:portType webservice 执行的操作 portType 对应接口 interface名称,其中的 operation 对应相应的方法名
-
<wsdl:serivce webservice 对外暴露 对外暴露的实现类,soup地址
-
<wsdl:binding webservice 使用的通信 绑定
JAXB
提供一个快捷的方式将Java对象与xml进行转换
package com.zhibin.masha;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Book {
private long id;
private String bookName;
private double price;
public Book() {
}
public Book(long id, String bookName, double price) {
super();
this.id = id;
this.bookName = bookName;
this.price = price;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book [id=" + id + ", bookName=" + bookName + ", price=" + price + "]";
}
}
package com.zhibin.masha;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class MyMarshaller {
public static void myMarshaller() throws JAXBException {
// 这里 是创建一个新实例,而并非直接new 一个新的对象,那么也就意味着
// 这个类是一个抽象类,不能直接创建对象。
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
marshaller.marshal(new Book(11,"java",25.8d),System.out);
}
public static void unMarshaller() throws JAXBException {
String xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\r\n"
+ "<book>\r\n"
+ " <bookName>java</bookName>\r\n"
+ " <id>11</id>\r\n"
+ " <price>25.8</price>\r\n"
+ "</book>\r\n"
+ "";
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Book book = (Book) unmarshaller.unmarshal(new StringReader(xmlString));
System.out.println(book);
}
public static void main(String[] args) throws JAXBException {
myMarshaller();
unMarshaller();
}
}
JAX-WS
用来完成WSDL到Java的转换
具体操作 使用wsdljava 命令 + 服务url 例如 wsdl2java http://localhost:8101/WebServiceLearnt?wsdl
执行完之后就可以回在 bin 目录里生成一个com文件夹,将此文件夹可以重新复制到新建的表示客户端的项目中
package com.zhibin.cfx;
public class Client {
public static void main(String[] args) {
// 调用方式
Hello client = new HelloImplService().getHelloImplPort();
System.out.println(client.sayHello("曹智斌", 23));
}
}
在生成的诸多文件中更多起作用的为implService文件和接口文件,例如本项目中的Hello接口和HelloImplService文件,其他的文件并不影响到具体的接口调用。
对于这些调用的文件,我们可以将其打成jar包,从而减小项目大小。