WebService技术详解CXF

WebService

WebService简介

Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。

简单的说,WebService就是一种跨编程语言和跨操作系统平台的远程调用技术。所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然。跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。 远程调用,就是一台计算机的应用可以调用其他计算机上的应用。例如:支付宝,支付宝并没有银行卡等数据,它只是去调用银行提供的接口来获得数据。还有天气预报等,也是气象局把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能。

WebService原理

XML,SOAP和WSDL就是构成WebService平台的三大技术 。

  • WebService采用Http协议来在客户端和服务端之间传输数据。WebService使用XML来封装数据,XML主要的优点在于它是跨平台的。
  • WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是SOAP协议规定的。
  • WebService服务器端首先要通过一个WSDL文件来说明自己有什么服务可以对外调用。简单的说,WSDL就像是一个说明书,用于描述WebService及其方法、参数和返回值。 WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的WSDL文件的地址。WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。

WebService交互的过程就是,WebService遵循SOAP协议通过XML封装数据,然后由Http协议来传输数据。

JAVA WebService规范

Java 中共有三种WebService 规范,分别是JAXM&SAAJ、JAX-WS(JAX-RPC)、JAX-RS。

(1)JAX-WS:

JAX-WS(Java API For XML-WebService)。早期的基于SOAP 的JAVA 的Web 服务规范JAX-RPC(java API For XML-Remote Procedure Call)目前已经被JAX-WS 规范取代,JAX-WS 是JAX-RPC 的演进版本,但JAX-WS 并不完全向后兼容JAX-RPC,二者最大的区别就是RPC/encoded 样式的WSDL,JAX-WS 已经不提供这种支持。JAX-RPC 的API 从JAVA EE5 开始已经移除,如果你使用J2EE1.4,其API 位于javax.xml.rpc.*包。JAX-WS(JSR 224)规范的API 位于javax.xml.ws.*包,其中大部分都是注解,提供API 操作Web 服务(通常在客户端使用的较多,由于客户端可以借助SDK 生成,因此这个包中的API 我们较少会直接使用)。

(2)JAXM&SAAJ:

JAXM(JAVA API For XML Message)主要定义了包含了发送和接收消息所需的API,相当于Web 服务的服务器端,其API 位于javax.messaging.*包,它是Java EE 的可选包,因此你需要单独下载。

SAAJ(SOAP With Attachment API For Java,JSR 67)是与JAXM 搭配使用的API,为构建SOAP 包和解析SOAP 包提供了重要的支持,支持附件传输,它在服务器端、客户端都需要使用。这里还要提到的是SAAJ 规范,其API 位于javax.xml.soap.*包。

JAXM&SAAJ 与JAX-WS 都是基于SOAP 的Web 服务,相比之下JAXM&SAAJ 暴漏了SOAP更多的底层细节,编码比较麻烦,而JAX-WS 更加抽象,隐藏了更多的细节,更加面向对象,实现起来你基本上不需要关心SOAP 的任何细节。那么如果你想控制SOAP 消息的更多细节,可以使用JAXM&SAAJ。

(3)JAX-RS:

JAX-RS 是JAVA 针对REST(Representation State Transfer)风格制定的一套Web 服务规范,由于推出的较晚,该规范(JSR 311,目前JAX-RS 的版本为1.0)并未随JDK1.6 一起发行。

WebService入门案例

服务端的实现

我们来实现一个天气系统的案例,客户端发送城市名称,服务器端回应相应的天气。

1.  编写SEI(Service Endpoint Interface),SEI在webservice中称为portType,在java中就是普通接口 public interface WeatherInterface {public String queryWeather(String cityName);
}
2.  编写SEI实现类,此类作为webservice提供服务类 @WebService     //@WebService表示该类是一个服务类,需要发布其中的public的方法
public class WeatherInterfaceImpl implements WeatherInterface {@Overridepublic String queryWeather(String cityName) {System.out.println("获取城市名"+cityName);String weather="暴雨";    return weather;}}
3.  第三步:发布服务,Endpoint类发布服务,publish方法,两个参数:1.服务地址;2.服务实现类 public class WeatherServer {public static void main(String[] args) {Endpoint.publish("http://127.0.0.1:12345/weather", new WeatherInterfaceImpl());}
}
4. 测试服务是否发布成功,通过阅读wsdl,确定客户端调用的接口、方法、参数和返回值存在,证明服务发布成功//我们在浏览器输入 http://127.0.0.1:12345/weather?wsdl 来获取wsdl文件进行阅读//wsdl,是以XML文件形式来描述WebService的”说明书”,有了说明书,我们才可以知道如何使用或是调用这个服务.//现在我们还不知道怎么去阅读,后面我们会详解,只要能获取到,就能确定WebService服务发布成功 1234567

这里写图片描述

客户端的实现

//客户端调用服务有很多种方法,我们先用工具生成客户端代码,后面会详解  //wsimport是jdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码).当然,无论服务器端的WebService是用什么语言写的,都可以生成调用webservice的客户端代码。1.创建一个客户端空项目,cmd命令行进入此项目的src目录使用以下命令生成客户端代码  wsimport -s . http://127.0.0.1:12345/weather?wsdl-s是指编译出源代码文件,后面的.()指將代码放到当前目录下.最后面的http….是指获取wsdl说明书的地址

这里写图片描述

2.编写客户端
public class WeatherClient {public static void main(String[] args) {//创建服务视图,视图是从wsdl文件的service标签的name属性获取WeatherInterfaceImplService weatherInterfaceImplService=new WeatherInterfaceImplService();  //获取服务实现类,实现类从wsdl文件的portType的name属性获取WeatherInterfaceImpl weatherInterfaceImpl=weatherInterfaceImplService.getPort(WeatherInterfaceImpl.class); //获取查询方法,从portType的operation标签获取String weather=weatherInterfaceImpl.queryWeather("北京");System.out.println(weather);}}

至此,我们的客户端就可以获取远程服务端的数据,接下来我们来详解一下各个部分。

WSDL

WSDL(Web Services Description Language), web服务描述语言,他是webservice服务端使用说明书,说明服务端接口、方法、参数和返回值,WSDL是随服务发布成功,自动生成,无需编写。

文档结构

这里写图片描述

Service:相关端口的集合,包括其关联的接口、操作、消息等。

Binding:特定端口类型的具体协议和数据格式规范

portType: 服务端点,描述 web service可被执行的操作方法,以及相关的消息,通过binding指向portType

message: 定义一个操作(方法)的数据参数

types: 定义 web service 使用的全部数据类型

阅读方式

WSDL文档应该从下往上阅读。

1.先看service标签,看相应port的binding属性,然后通过值查找上面的binding标签。

2.通过binding标签可以获得具体协议等信息,然后查看binding的type属性

3.通过binding的type属性,查找对应的portType,可以获得可操作的方法和参数、返回值等。

4.通过portType下的operation标签的message属性,可以向上查找message获取具体的数据参数信息。

SOAP

SOAP即简单对象访问协议,他是使用http发送的XML格式的数据,它可以跨平台,跨防火墙,SOAP不是webservice的专有协议。

SOAP=http+xml

SOAP结构

必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
可选的 Header 元素,包含头部信息
必需的 Body 元素,包含所有的调用和响应信息
可选的 Fault 元素,提供有关在处理此消息所发生错误的信息

这里写图片描述

我们来看一下我们上面天气程序发送的数据的格式,这需要一个工具TCP/IP Monitor ,Eclipse自带的Debug工具之一,用于捕获Http、TCP/IP协议包。原理是一个代理服务,客户端先把数据发送到代理服务,然后代理服务再把数据发送到服务器,这样就能获取请求数据和响应数据。

第一步:打开这个工具,选择other,然后输入TCP/IP Monitor

这里写图片描述

第二步:设置要代理的服务器

这里写图片描述

第三步:详细设置

第一个参数是代理服务器端口,我们设置为54321
第二个参数是被代理服务器的地址,第三个参数是被代理服务器的端口
第四个参数要选择为TCP/IP

这里写图片描述

第四步:检测是否设置成功,我们访问代理服务器来获得wsdl文件

这里写图片描述

第五步:设置成功后,我们需要改一下客户端要连接的服务器,改成代理服务器的端口

WeatherInterfaceImplService里的所有原来地址的端口改为54321

这里写图片描述

第六步:我们启动我们的客户端,获取请求数据和响应数据

请求 //先发送get请求,去获得wsdl文件,然后获得方法、参数等信息
GET /weather?wsdl HTTP/1.1
User-Agent: Java/1.8.0_111
Host: 127.0.0.1:54321
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive//发送数据
POST /weather HTTP/1.1
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://ws.cad.com/WeatherInterfaceImpl/queryWeatherRequest"
User-Agent: JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e
Host: 127.0.0.1:54321
Connection: keep-alive
Content-Length: 203<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:queryWeather xmlns:ns2="http://ws.cad.com/">
<arg0>北京</arg0>
</ns2:queryWeather>
</S:Body>
</S:Envelope>
响应数据 HTTP/1.1 200 OK
Date: Tue, 25 Jul 2017 05:05:58 GMT
Transfer-encoding: chunked
Content-type: text/xml;charset=utf-8//响应wsdl内容,来获得方法、参数等信息
899
<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. --><definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws.cad.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.cad.com/" name="WeatherInterfaceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://ws.cad.com/" schemaLocation="http://127.0.0.1:54321/weather?xsd=1"></xsd:import>
</xsd:schema>
</types>
<message name="queryWeather">
<part name="parameters" element="tns:queryWeather"></part>
</message>
<message name="queryWeatherResponse">
<part name="parameters" element="tns:queryWeatherResponse"></part>
</message>
<portType name="WeatherInterfaceImpl">
<operation name="queryWeather">
<input wsam:Action="http://ws.cad.com/WeatherInterfaceImpl/queryWeatherRequest" message="tns:queryWeather"></input>
<output wsam:Action="http://ws.cad.com/WeatherInterfaceImpl/queryWeatherResponse" message="tns:queryWeatherResponse"></output>
</operation>
</portType>
<binding name="WeatherInterfaceImplPortBinding" type="tns:WeatherInterfaceImpl">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
<operation name="queryWeather">
<soap:operation soapAction=""></soap:operation>
<input>
<soap:body use="literal"></soap:body>
</input>
<output>
<soap:body use="literal"></soap:body>
</output>
</operation>
</binding>
<service name="WeatherInterfaceImplService">
<port name="WeatherInterfaceImplPort" binding="tns:WeatherInterfaceImplPortBinding">
<soap:address location="http://127.0.0.1:54321/weather"></soap:address>
</port>
</service>
</definitions>
0//响应数据
HTTP/1.1 200 OK
Date: Tue, 25 Jul 2017 05:05:59 GMT
Transfer-encoding: chunked
Content-type: text/xml; charset=utf-8df
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body><ns2:queryWeatherResponse xmlns:ns2="http://ws.cad.com/"><return>暴雨</return> </ns2:queryWeatherResponse> 
</S:Body>
</S:Envelope>
0

UDDI

UDDI 是一种目录服务,企业可以使用它对 Web services 进行注册和搜索。
如果我们要使用一种服务,但是不知道地址(wsdl等),我们就可以在UDDI中查找。
大部分情况下,我们都是知道服务地址的。

Webservice的客户端调用方式

一:生成客户端调用方式

wsimport是jdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码).
wsimport.exe位于JAVA_HOME\bin目录下 
常用参数为:-d<目录>  - 将生成.class文件。默认参数。-s<目录> - 将生成.java文件。-p<生成的新包名> -将生成的类,放于指定的包下

调用公网的手机归属地查询服务

公网服务地址 (里面提供了很多免费调用的服务)
http://www.webxml.com.cn/zh_cn/index.aspx

第一步:wsimport生成客户端代码 wsimport -p cn.cad.mobile -s . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl会出现一些警告,是因为服务端提供的一些方法是SOAP1.2标准的,这个工具没有实现SOAP1.2标准的生成方式。    

这里写图片描述

第二步:查看wsdl文件,获取我们需要的信息

这里写图片描述

第三步:根据获取到的服务名等信息来创建我们的客户端  public class MobileClient {public static void main(String[] args) {//创建服务视图MobileCodeWS mobileCodeWS=new MobileCodeWS();//获取服务实现类MobileCodeWSSoap mobileCodeWSSoap= mobileCodeWS.getPort(MobileCodeWSSoap.class);//调用查询方法String message=mobileCodeWSSoap.getMobileCodeInfo("xxxxxxxx", null);System.out.println(message);}
}第四步:获取到信息 1

这里写图片描述

还有天气等服务,自己可以去实现一下。

该种方式使用简单,但一些关键的元素在代码生成时写死在生成代码中,不方便维护,所以仅用于测试。

二:service编程调用方式

public class MobileClient2 {public static void main(String[] args) throws IOException {//创建WSDL文件的URLURL wsdlDocumentLocation=new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl"); //创建服务名称//1.namespaceURI - 命名空间地址//2.localPart - 服务视图名QName serviceName=new QName("http://WebXml.com.cn/","MobileCodeWS");Service service=Service.create(wsdlDocumentLocation, serviceName);//获取服务实现类MobileCodeWSSoap mobileCodeWSSoap= service.getPort(MobileCodeWSSoap.class);//调用方法String message=mobileCodeWSSoap.getMobileCodeInfo("XXXXXXX", null);System.out.println(message);}}

该种方式可以自定义命名空间,服务视图名等元素,方便以后维护,是一种标准的开发方式 。

三:HttpURLConnection调用方式

这种方式是由自己编写客户端,不再由工具生成,比较麻烦。

开发步骤: 第一步:创建服务地址第二步:打开一个通向服务地址的连接第三步:设置参数第四步:组织SOAP数据,发送请求第五步:接收服务端响应 
public class MobileClient2 {public static void main(String[] args) throws IOException {//第一步:创建服务地址,不是WSDL地址URL url = new URL("http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx");//第二步:打开一个通向服务地址的连接HttpURLConnection connection = (HttpURLConnection) url.openConnection();//第三步:设置参数//3.1发送方式设置:POST必须大写connection.setRequestMethod("POST");//3.2设置数据格式:content-typeconnection.setRequestProperty("content-type", "text/xml;charset=UTF-8");//3.3设置输入输出,因为默认新创建的connection没有读写权限,connection.setDoInput(true);connection.setDoOutput(true);//第四步:组织SOAP数据,发送请求String soapXML = getXML("XXXXXXX");OutputStream os = connection.getOutputStream();os.write(soapXML.getBytes());//第五步:接收服务端响应,打印int responseCode = connection.getResponseCode();if(200 == responseCode){//表示服务端响应成功InputStream is = connection.getInputStream();//将字节流转换为字符流InputStreamReader isr = new InputStreamReader(is,"utf-8");//使用缓存区BufferedReader br = new BufferedReader(isr);StringBuilder sb = new StringBuilder();String temp = null;while(null != (temp = br.readLine())){sb.append(temp);}System.out.println(sb.toString());is.close();isr.close();br.close();}os.close();}//组织数据,将数据拼接一下public static String getXML(String phoneNum){String soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+"<soap:Body>"+"<getMobileCodeInfo xmlns=\"http://WebXml.com.cn/\">"+"<mobileCode>"+phoneNum+"</mobileCode>"+"<userID></userID>"+"</getMobileCodeInfo>"+"</soap:Body>"+"</soap:Envelope>";return soapXML;}
}

这里写图片描述

使用注解修改WSDL内容

作用:
通过注解,可以更加形像的描述Web服务。对自动生成的wsdl文档进行修改,为使用者提供一个更加清晰的wsdl文档

WebService的注解都位于javax.jws包下: @WebService-定义服务,在类上边targetNamespace:指定命名空间name:portType的名称portName:port的名称serviceName:服务名称endpointInterface:SEI接口地址,如果一个服务类实现了多个接口,只需要发布一个接口的方法,可通过此注解指定要发布服务的接口。 @WebMethod-定义方法,在公开方法上边operationName:方法名exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法,默认是false @WebResult-定义返回值,在方法返回值前边name:返回结果值的名称 @WebParam-定义参数,在方法参数前边name:指定参数的名称
//以我们前面做的天气案例为例子@WebService(targetNamespace="http://service.cad.com",portName="WeatherSOAPPort",serviceName="WeatherWSS",name="WeatherSOAP"  
)
public class WeatherInterfaceImpl implements WeatherInterface {@WebMethod(operationName="getWeather",exclude=false)public @WebResult(name="result")String queryWeather(@WebParam(name="cityName")String cityName) {System.out.println("获取城市名"+cityName);String weather="暴雨";    return weather;}}
然后重新发布服务,我们再访问wsdl文件,就可以看到我们改变的内容

这里写图片描述

CXF

CXF简介

CXF是一个开源的WebService框架。Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。

支持多种标准

  • 支持 JAX-WS、 JAX-WSA、JSR-181 和 SAAJ;
  • 支持 SOAP 1.1、1.2、WS-I BasicProfile、WS-Security、WS-Addressing、WS-RM 和 WS-Policy;
  • 支持 WSDL 1.1 、2.0;
  • 支持 MTOM;

它支持多种协议,比如:SOAP1.1,1,2、XML/HTTP、RESTful HTTP 或者 CORBA。CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WS。C,c++,C#)

Cxf是基于SOA总线结构,依靠spring完成模块的集成,实现SOA方式。

灵活的部署:可以运行有Tomcat,Jboss,Jetty(内置),weblogic上面。

CXF入门案例

我们还以昨天的天气服务为案例来看一下CXF的开发过程。

服务端的实现

1.创建一个空的java项目,创建一个lib目录,将所有jar包放入lib目录然后为工程引入jar包,选择build path,然后Add JARS,只用选择cxf-manifest.jar即可。

这里写图片描述

这里写图片描述

2.创建一个SEI接口,需要在接口上添加@WebService注解@WebService
public interface WeatherInterface {public String queryWeather(String cityName);
}
3.创建SEI接口实现类 public class WeatherInterfaceImpl implements WeatherInterface {public String queryWeather(String cityName) {if("河南".equals(cityName)) {return "热爆炸";}else {return "冰雹";}}
}
4.发布服务 public class WeatherServer {public static void main(String[] args) {//创建服务工厂BeanJaxWsServerFactoryBean jaxWsServerFactoryBean=new JaxWsServerFactoryBean();//设置服务接口jaxWsServerFactoryBean.setServiceClass(WeatherInterface.class);//设置服务实现类jaxWsServerFactoryBean.setServiceBean(new WeatherInterfaceImpl());//设置服务地址jaxWsServerFactoryBean.setAddress("http://127.0.0.1:12345/weather");//创建服务jaxWsServerFactoryBean.create();}}
5.访问服务的wsdl文件地址,看服务是否发布成功http://127.0.0.1:12345/weather?wsdl

这里写图片描述

发布SOAP1.2的服务端

SOAP分为1.1版本和1.2版本。JDK1.6并不支持1.2,我们可以通过CXF来发布SOAP1.2的服务端。
只需要在接口上添加注解 @BindingType(SOAPBinding.SOAP12HTTP_BINDING)。然后重新发布服务即可

import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;@WebService
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public interface WeatherInterface {public String queryWeather(String cityName);
}

客户端的实现

Wsdl2java命令是CXF提供的生成客户端的工具,他和wsimport类似,可以根据WSDL生成客户端代码 Wsdl2java常用参数:
-d,指定输出目录
-p,指定包名,如果不指定该参数,默认包名是WSDL的命名空间的倒序 Wsdl2java支持SOAP1.1和SOAP1.2
1.我们先创建一个客户端项目,然后引入jar包,和上面一样,使用Add JARS选择cxf-manifest.jar即可然后使用工具生成客户端wsdl2java -p com.cad.cxf -d . http://127.0.0.1:12345/weather?wsdl 

这里写图片描述

2.创建客户端 public class WeatherClient {public static void main(String[] args) {JaxWsProxyFactoryBean jaxWsProxyFactoryBean=new JaxWsProxyFactoryBean();//设置服务接口jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class); //设置服务地址jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:12345/weather");//获取服务接口实例WeatherInterface weatherInterface=(WeatherInterface) jaxWsProxyFactoryBean.create();//调用方法String message=weatherInterface.queryWeather("河南");System.out.println(message);}}

CXF+Spring整合发布SOAP模式的服务

服务端的实现

1.创建WEB项目,导入jar包 1
2.创建SEI接口 @WebService
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public interface WeatherInterface {public String queryWeather(String cityName);
}
3.创建SEI实现类 
public class WeatherInterfaceImpl implements WeatherInterface {public String queryWeather(String cityName) {if("河南".equals(cityName)) {return "热爆炸";}else {return "冰雹";}}
}
4.配置spring配置文件,applicationContext.xml  <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsdhttp://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsdhttp://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"><!--jaxws:server发布SOAP协议的服务 ,对JaxWsServerFactoryBean类封装-->
<!--serviceClass属性是服务接口,address代表地址,因为我们是web服务,不需要输入ip。serviceBean是服务实现类-->
<jaxws:server serviceClass="com.cad.cxf.WeatherInterface" address="/weather"><jaxws:serviceBean><ref bean="weatherInterfaceImpl"/></jaxws:serviceBean>
</jaxws:server>
<bean name="weatherInterfaceImpl" class="com.cad.cxf.WeatherInterfaceImpl"></bean>
</beans>                            
5.配置web.xml <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"><display-name>CXFSpringDemo</display-name>//配置Tomcat启动时加载Spring配置文件 <context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>//配置CXF提供的Servlet<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><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list>
</web-app>
6.部署到Tomcat下,发布服务,并访问 http://localhost:8080/CXFSpringDemo/ws/weather?wsdl

这里写图片描述

客户端的实现

1.创建项目,导入jar包,生成客户端 wsdl2java -p com.cad.cxf -d . http://localhost:8080/CXFSpringDemo/ws/weather?wsdl

这里写图片描述

2.配置Spring文件  <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsdhttp://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsdhttp://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"><!-- <jaxws:client实现客户端 ,对JaxWsProxyFactoryBean类封装-->   <!-- address是服务地址,servicelass是服务接口,返回服务实现类-->   <jaxws:client id="weatherClient" address="http://localhost:8080/CXFSpringDemo/ws/weather" serviceClass="com.cad.cxf.WeatherInterface"/>
</beans>
3.通过Spring容器获取服务实现类,调用方法 public class WeatherClient {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");WeatherInterface  weatherInterface = (WeatherInterface) context.getBean("weatherClient");String message=weatherInterface.queryWeather("河南");System.out.println(message);}}

这里写图片描述

CXF发布REST模式的服务

REST即表述性状态传递(英文:Representational State Transfer,简称REST),是一种软件架构风格。

因为REST模式的Web服务与复杂的SOAP和XML-RPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现rest服务采用HTTP 做传输协议,REST 对于HTTP 的利用实现精确的资源定位。

例如:
非rest方式:http://ip:port/queryUser.action?userType=student&id=001 Rest方式:http://ip:port/user/student/query/001 
1.创建一个项目,导入CXF jar包 1
2.创建一个实体类 Student   
@XmlRootElement(name="student")可以实现XML和对象之间的转换,name属性指定根元素@XmlRootElement(name="student")
public class Student {private int id;private String name;private Date birthday;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}
3.创建SEI接口 @WebService
//@Path("/student")就是指定访问该接口的路径
@Path("/Student")
public interface StudentInterface {//指定请求方式,如果服务端发布的时候指定的是GET(POST),那么客户端访问时必须使用GET(POST@GET//指定服务数据类型,可以是XML,json等数据类型@Produces(MediaType.APPLICATION_XML)//@Path("/query/{id}")指定该方法的路径,“{id}”指参数,多个参数,以“/”隔开,放到“{}”中@Path("/query/{id}")public Student queryStudent(@PathParam("id")int id);@GET@Produces(MediaType.APPLICATION_XML)@Path("/queryList/{name}")public List<Student> queryList(@PathParam("name")String name);
}
4.创建SEI实现类 public class StudentInterfaceImpl implements StudentInterface {@Overridepublic Student queryStudent(int id) {Student s=new Student();s.setId(666);s.setName("张三");s.setBirthday(new Date());return s;}@Overridepublic List<Student> queryList(String name) {Student s=new Student();s.setId(666);s.setName("张三");s.setBirthday(new Date());Student s2=new Student();s2.setId(888);s2.setName("李四");s2.setBirthday(new Date());List<Student> l=new ArrayList<Student>();l.add(s);l.add(s2);return l;}}
5.发布服务 public class StudentServer {public static void main(String[] args) {JAXRSServerFactoryBean jaxrsServerFactoryBean=new JAXRSServerFactoryBean();//设置服务实现类jaxrsServerFactoryBean.setServiceBean(new StudentInterfaceImpl());//设置资源类,如果有多个资源类,可以以“,”隔开,例如Student.class StudentInterface.class都是资源类,但是StudentInterfaceImpl里面已经包含了Student.class StudentInterface.class,所以不用重复指定jaxrsServerFactoryBean.setResourceClasses(StudentInterfaceImpl.class); //设置服务地址jaxrsServerFactoryBean.setAddress("http://127.0.0.1:12345/Class");//发布服务jaxrsServerFactoryBean.create();}}
6.测试服务 访问query方法 http://127.0.0.1:12345/Class/Student/query/001

这里写图片描述

访问queryList方法 http://127.0.0.1:12345/Class/Student/queryList/xxx

这里写图片描述

如果服务端发布时指定请求方式是GET(POST),客户端必须使用GET(POST)访问服务端,否则会报异常。
如果在同一方法上同时指定XML和JSON媒体类型,在GET请求下,默认返回XML,在POST请求下,默认返回JSON

CXF+Spring整合发布REST模式的服务

1.创建web项目,引入jar包1
2.创建一个实体类 Student   
@XmlRootElement(name="student")可以实现XML和对象之间的转换,name属性指定根元素@XmlRootElement(name="student")
public class Student {private int id;private String name;private Date birthday;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}
3.创建SEI接口 @WebService
//@Path("/student")就是指定访问该接口的路径
@Path("/Student")
public interface StudentInterface {//指定请求方式,如果服务端发布的时候指定的是GET(POST),那么客户端访问时必须使用GET(POST@GET//指定服务数据类型,可以是XML,json等数据类型@Produces(MediaType.APPLICATION_XML)//@Path("/query/{id}")指定该方法的路径,“{id}”指参数,多个参数,以“/”隔开,放到“{}”中@Path("/query/{id}")public Student queryStudent(@PathParam("id")int id);@GET@Produces(MediaType.APPLICATION_XML)@Path("/queryList/{name}")public List<Student> queryList(@PathParam("name")String name);
}
4.创建SEI实现类 public class StudentInterfaceImpl implements StudentInterface {@Overridepublic Student queryStudent(int id) {Student s=new Student();s.setId(666);s.setName("张三");s.setBirthday(new Date());return s;}@Overridepublic List<Student> queryList(String name) {Student s=new Student();s.setId(666);s.setName("张三");s.setBirthday(new Date());Student s2=new Student();s2.setId(888);s2.setName("李四");s2.setBirthday(new Date());List<Student> l=new ArrayList<Student>();l.add(s);l.add(s2);return l;}}
第五步:配置Spring配置文件,applicationContext.xml <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsdhttp://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsdhttp://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"><!-- <jaxrs:server发布REST的服务 ,对JAXRSServerFactoryBean类封装-->  <jaxrs:server address="/user"><jaxrs:serviceBeans><ref bean="studentInterface"/></jaxrs:serviceBeans></jaxrs:server><!-- 配置服务实现类 --><bean name="studentInterface" class="com.cad.rest.StudentInterfaceImpl"/>
</beans>
6.配置web.xml文件 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>ws_2_cxf_spring_server</display-name><!-- 设置spring的环境 --><context-param><!--contextConfigLocation是不能修改的  --><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 配置CXF的Servlet --><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><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list>
</web-app>
7.部署到Tomcat中,发布服务,测试一下
http://127.0.0.1:8080/CXFRestDemo/ws/user/Student/query/100

综合案例:手机归属地查询

1.创建web项目,导入 CXF jar包 1
2.生成公网提供的手机归属地查询的客户端 
wsdl2java -p com.cad.mobile -d . http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl

这里写图片描述

3.编写我们自己的SEI接口 @WebService
public interface MobileInterface {public String  queryMobile(String phoneNum);
}
4.编写我们的SEI实现类 ,里面调用公网客户端的查询方法,我们在Spring配置客户端,然后注入即可 public class MobileInterfaceImpl implements MobileInterface {//公网客户端,提供set方法 以便注入private MobileCodeWSSoap mobileClient;//调用公网的查询方法public String queryMobile(String phoneNum) {return mobileClient.getMobileCodeInfo(phoneNum, "");}public MobileCodeWSSoap getMobileClient() {return mobileClient;}public void setMobileClient(MobileCodeWSSoap mobileClient) {this.mobileClient = mobileClient;}}
5.配置Spring 配置文件 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsdhttp://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsdhttp://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"><!-- 配置公网客户端 --><jaxws:client id="mobileClient" address="http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx" serviceClass="com.cad.mobile.MobileCodeWSSoap"/> <!-- <jaxws:server发布我们的服务-->    <jaxws:server address="/mobile" serviceClass="com.cad.server.MobileInterface"><jaxws:serviceBean><ref bean="mobileServer"/></jaxws:serviceBean></jaxws:server> <!-- 配置我们的服务实现类 --><bean name="mobileServer" class="com.cad.server.MobileInterfaceImpl"><property name="mobileClient" ref="mobileClient"/></bean>     </beans>        
6.创建查询页面 <body><form action="MobileServlet" method="post">手机号归属地查询:<input type="text" name="phoneNum"><input type="submit" value="查询"><br>查询结果:${result}</form></body>
7.创建处理的Servlet@WebServlet("/MobileServlet")
public class MobileServlet extends HttpServlet {private MobileInterface mobileServer;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取页面的电话号String phoneNum = request.getParameter("phoneNum");if(null != phoneNum && !"".equals(phoneNum)){//获取Spring容器ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());//获取我们的服务实现类mobileServer = (MobileInterface) context.getBean("mobileServer");//调用查询方法String result = mobileServer.queryMobile(phoneNum);request.setAttribute("result", result);}//请求转发  request.getRequestDispatcher("/index.jsp").forward(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}
8.配置web.xml<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"><display-name>MobileDemo</display-name><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list><context-param><!--contextConfigLocation是不能修改的  --><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 配置CXF的Servlet --><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></web-app>
9.部署Tomcat,访问测试

这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java webservice详解

文章目录1 webservice概述2 webservice核心要素2.1 SOAP2.2 WSDL3 webservice的使用场景4 webservice的结构5 Java中的webservice5.1 webservice服务端5.2 webservice客户端6 WDSL文件说明7 webservice 请求与响应监控8 webservice 在Tomcat中发布9 在Spring中使用webservice1 …

hibernate mysql cascade_Hibernate第五篇【inverse、cascade属性详解】

前言上一篇博文已经讲解了一对多和多对一之间的关系了&#xff0c;一对多和多对一存在着关联关系(外键与主键的关系)。本博文主要讲解Inverse属性、cascade属性。这两个属性对关联关系都有影响Inverse属性Inverse属性&#xff1a;表示控制权是否转移..true:控制权已转移【当前一…

spring boot中打包插件spring-boot-maven-plugin和maven-jar-plugin的关联

简介 用spring boot快速开发时&#xff0c;通常用spring-boot-maven-plugin插件将springboot的应用程序打包成jar文件&#xff0c;然后通过java -jar运行&#xff0c;很方便。但是如果是部署到服务器上&#xff0c;每次更改代码后替换的包都比较大&#xff0c;至少30MB以上&am…

Maven父子结构的项目依赖使用以及打包依赖_微服务项目(maven父子级项目)怎么打包

Maven父子结构的项目依赖使用以及打包依赖 1&#xff1a;在父子结构项目中&#xff0c;如果要是用其他模块的类。在当前项目中的pom中 加入 其他模块的配置 <dependency><groupId>com.spring.mySpring</groupId><artifactId>mySpring-utils</artif…

搭建一个完整的微服务项目

一.项目技术架构 1.技术栈 前台技术 Node.js、Npm、Vue.js、WebPack、Vue Cli、Element UI 后台架构 微服务架构&#xff1a;按照功能拆分N多个服务&#xff0c;每个服务可以独立技术选型,独立开发,独立部署,独立运维.&#xff0c;单个服务使用基于ssm的springboot&#xff0…

java 雅思_基于JAVA的雅思考试管理系统的设计与实现(SSH,MySQL)(含录像)

基于JAVA的雅思考试管理系统的设计与实现(SSH,MySQL)(含录像)(任务书,毕业论文12000字,程序代码,MySQL数据库)本文分析了基于JAVA的雅思考试管理系统的设计与实现技术&#xff0c;结合实际提出了本系统的总体结构设计和主要模块的功能实现。本系统分为二个子系统:管理员子系统&…

java开发利器 源码_Java开发的利器: 反编译工具 JD-GUI

老赵说起来也能算个Java程序员&#xff0c;可是写过的Java代码并不多&#xff0c;可老赵实实在在是从程序员干起的。虽然肚子里也装了不少的东西&#xff0c;可作为一件乐此不疲的事情&#xff0c;就是看那些所谓“高人”的代码。高人们的行事风格&#xff0c;十人十样&#xf…

Maven搭建Nexus私服

私服的介绍 1 什么是私服 私服是一种特殊的远程仓库&#xff0c;它是架设在局域网的仓库服务&#xff0c;私服代理广域网上的远程仓库&#xff0c;供局域网使用。 在企业开发中&#xff0c;私服的建设是有必要的&#xff0c;其好处如下&#xff1a; 1.1 节省资金、外网带宽…

Java啤酒生产系统描述_Java描述设计模式(03):工厂方法模式

一、工厂方法模式1、生活场景系统常见的数据导出功能&#xff1a;数据导出PDF、WORD等常见格式。2、工厂方法模式是类的创建模式&#xff0c;又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。工厂方法模式的用意是定义一个创建产品对象的工…

@Autowired(required=false)注入注意的问题

1、前言 在使用spring开发过程中&#xff0c;我们基本上都是使用Autowired这个注解&#xff0c;用来注入已有的bean。但是有些时候&#xff0c;会注入失败。当我们加上参数&#xff08;requiredfalse&#xff09;就能解决。今天整理一个我在实际开发中的例子 2、required属性…

什么是ip地址、子网掩码、网关和DNS?

什么是ip地址、子网掩码、网关和DNS&#xff1f; 什么是ip地址&#xff1f; IP是32位二进制数据&#xff0c;通常以十进制表示&#xff0c;并以“.”分隔。IP地址是一种逻辑地地址&#xff0c;用来标识网络中一个个主机&#xff0c;IP有唯一性&#xff0c;即每台机器的IP在全…

Dubbo:RPC原理

1、RPC原理 一次完整的RPC调用流程如下&#xff1a; 1&#xff09;服务消费方&#xff08;client&#xff09;调用以本地调用方式调用服务&#xff1b; 2&#xff09;client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体&#xff1b; 3&#xff09;clie…

java jni日志输出_java打印Jni层log

要在java层打印c的log必须引入这个头文件的宏定义:#ifndef __LOG#define __LOG#ifdef __cplusplusextern "C"{#endif#include//宏定义类似java 层的定义,不同级别的Log LOGI, LOGD, LOGW, LOGE, LOGF。 对就Java中的 Log.i log.d#define LOG_TAG "HelloJni"…

Dubbo基本原理机制

分布式服务框架&#xff1a; 高性能和透明化的RPC远程服务调用方案SOA服务治理方案Apache MINA 框架基于Reactor模型通信框架&#xff0c;基于tcp长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯&#xff0c; 适合于小数据量大并发的服务调用&#xff0c;以及服务消费者机器…

Dubbo是如何进行远程服务调用的?(源码流程跟踪)

首先会分析Dubbo是如何进行远程服务调用的&#xff0c;如果不了解dubbo的服务暴露和服务调用&#xff0c;请去看前两篇dubbo的文章&#xff0c;然后后面我还会说一下dubbo的SPI机制 当我们在使用reference 注解的时候&#xff0c;来调用我们的提供者的Service对象的时候&#…

Redis五种数据类型及应用场景

Redis五种数据类型及应用场景 MySqlMemcached架构的问题 实际MySQL是适合进行海量数据存储的&#xff0c;通过Memcached将热点数据加载到cache&#xff0c;加速访问&#xff0c;很多公司都曾经使用过这样的架构&#xff0c;但随着业务数据量的不断增加&#xff0c;和访问量的…

WebSocket介绍和Socket的区别

WebSocket介绍与原理 WebSocket protocol 是HTML5一种新的协议。它实现了浏览器与服务器全双工通信(full-duplex)。一开始的握手需要借助HTTP)请求完成。 ——百度百科 目的&#xff1a;即时通讯&#xff0c;替代轮询 应用场景&#xff1a;网站上的即时通讯是很常见的&#xf…

WebSocket协议入门介绍

文章目录WebSocket协议是什么WebSocket是应用层协议WebSocket与Http的区别为什么要使用WebSocket如何使用WebSocket客户端API在客户端使用WebSocket在服务端使用WebSocket反向代理对WebSocket的支持WebSocket协议是什么 WebSocket是应用层协议 WebSocket是基于TCP的应用层协议…

远程ykvm 插件移值java_Centos7 命令行下kvm安装windows,linux

查看是否支持egrep "svm|vmx" /proc/cpuinfo |uniq安装软件yum install libvirt -yyum -y install qemu-kvmsystemctl enable libvirtd && systemctl start libvirtd# 启动libvitd服务查看 ip add #查看是否有 virbr0网卡 yum install virt-installcentos7 例…

php7.0扩展yac,php扩展之yac安装

git克隆$ git clone https://github.com/laruence/yac.git解压安装注意这里的php-config可能不一样查看php-config位置$whereis php编译安装$ cd yac$ phpize$ ./configure --with-php-config/usr/bin/php-config$ make$ make install修改php.ini,载入扩展,重启php-fpmextensio…