一、Webservice简介
1、 WebService是一种跨编程语言和跨操作系统平台的远程调用技术。具有异构平台的互通性,软件的复用性等优点。
2、WebService的三要素:
(1)SOAP(简单对象访问协议),基于HTTP协议,采用XML格式,用来传递信息的格式。
(2)WSDL: 用来描述如何访问具体的服务。(相当于说明书)
(3)UDDI: 用户自己可以按UDDI标准搭建UDDI服务器,用来管理,分发,查询WebService 。其他用户可以自己注册 发布WebService调用。
二、实现
1、在编写客户端代码时,需要先了解WSDL文件的基本信息。在所给的WebService访问地址的后面加上“?wsdl”,在 在浏览器中打开访问webservice接口的wsdl文件。需要了解wsdl文件的三个基本属性,在客户端编码时,需要用到这几个属性值。
2、 基于JDK开发的实现方式
服务端的实现一般分为三步:
(1)编写接口
public interface WeatherWS {public String getMsg(String CityName);
}
(2)实现类(需要在实现类中加入注解@Webservice)
@WebService
public class WeatherWSImpl implements WeatherWs{@Overridepublic String getMsg(String CityName) {return "大阴天"+CityName;}
}
(3)发布
public class AppWebService
{public static void main( String[] args ){Endpoint.publish("http://localhost:8080/webservice",new WeatherImpl());System.out.println("发布成功");}
}
其中http://localhost:8080/webservice为发布地址,运行程序后,可用http://localhost:8080/webservice?wsdl访问,访问发布成功后的wsdl文件。
客户端的实现步骤:(并未与上述的服务端配对,只是实现思路)
(1)使用wsimport命令,根据服务端发布的地址在所建项目的src目录下,生成代码。
在黑窗口切换到所建立客户端项目的src目录,再采用wsimport命令生成代码,操作如下图。
(2)编写实现类
public class WeatherClient{public static void main(String[] args) {//1.创建服务类,wsdl文件的server属性。MobileCodeWS ms=new MobileCodeWS();//2.创建实现类对象,wsdl文件的端口类型属性。MobileCodeWSSoap port= ms.getPort(MobileCodeWSSoap.class);//3.获取实现方法,wsdl文件的端口类型属性里面的实现方法。String msg=port.getMobileCodeInfo("手机号码",null);System.out.println(msg);}
}
另外,有些网络上发布的地址,在生成客户端代码时,会出现错误。例如http://www.webxml.com.cn/zh_cn/web_services.aspx 发布的天气预报,根据其wsdl文件生成代码时,会出现错误。
解决方法:把网络上的wsdl文件源码复制下来,在本地创建一个wsdl文件,然后用 <s:any minOccurs="2" maxOccurs="2" />替换掉<s:element ref="s:schema" /> <s:any /> 部分,再根据本地wsdl生成代码即可。
3、基于CXF的实现方式
(1)CXF简介:Apache CXF ( CXF=celtix+Xfire的组合)是一个开源的 WebService 框架,CXF可以用来构建和开发 WebService,CXF 大大简化了WebService并且可以天然地和 Spring 进行无缝集成,核心是org.apache.cxf.Bus(总线)。
(2)实现
前提:需要下载CXF框架,并配置好CXF的环境变量,然后把CXF框架中的lib文件下的jar包添加到项目中(客户端和服务端端都一样)。
服务端代码的编写一般分为三步:
第一、编写接口
@WebService
public interface WeatherWS {public String getMsg(String CityName);
}
第二、实现类
public class WeatherImpl implements WeatherWs{@Overridepublic String getMsg(String CityName) {return "大晴天"+CityName;}
}
第三、发布
public class Weathermain{public static void main(String[] args) {JaxWsServerFactoryBean factoryBean=new JaxWsServerFactoryBean();//1.设置服务地址factoryBean.setAddress("http://localhost:8888/weather");//2.设置服务接口factoryBean.setServiceClass(WeatherWs.class);//3.设置服务实现类factoryBean.setServiceBean(new WeatherImpl());//通过工厂创建服务factoryBean.create();System.out.println("发布成功!");}
}
客户端的实现:(并未与上述的服务端配对,只是实现思路)
第一、类似于JDK的实现方式,通过 “wsdl2java –d . wsdl文件” 命令,在src目录下生成代码。
第二、编写实现代码
public class test {public static void main(String[] args) {JaxWsProxyFactoryBean svr = new JaxWsProxyFactoryBean();//1、设置地址,在wsdl文件上有。svr.setAddress("http://localhost:8888/weather");//2.实现服务接口,为wsdl上端口类型属性svr.setServiceClass(Weatherdao.class);//3.创建实现对象Weatherdao wea=(Weatherdao)svr.create();//调用方法String Msg=wea.getMsg("海南");System.out.println("jname"+name);}
}
4、Sprintboot整合CXF实现Webservice
(1)添加依赖(我在使用Springboot版本<version>2.2.1.RELEASE</version>,发生运行错误,可以使用<version>2.0.1.RELEASE</version>这个版本)
<!--CXF依赖包,开发webservice--><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.1.11</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.1.11</version></dependency>
(2)编写代码
服务端代码的编写:
第一、编写接口
@WebService(targetNamespace="http://webservice_cxf.prior.prior/")
public interface WeatherWS{@WebMethodpublic @WebResult String WeatherMsg(@WebParam(CityNeme= "userName") String CityNeme);
}
第二,实现类
@Component("WeatherImpl")
@WebService(serviceName="WeatherService",//【对外发布的服务名 】:需要见名知意targetNamespace="http://webservice_cxf.prior.prior/",//【名称空间】:【实现类包名的反缀】endpointInterface = "prior.prior.webservice_cxf.WeatherWs")//【服务接口全路径】 【接口的包名】
public class WeatherImpl implements WeatherWs{@Overridepublic String WeatherMsg(String CityName) {return "大阴天: " + CityName;}
}
第三、发布
@Configuration//注册到spring启动中
public class CxfConfig {@Beanpublic ServletRegistrationBean dispatcherServlet() {return new ServletRegistrationBean(new CXFServlet(), "/cxf/*");// 发布服务名称 localhost:8080/cxf}@Bean(name = Bus.DEFAULT_BUS_ID)public SpringBus springBus() {return new SpringBus();}@Beanpublic Endpoint hello() {EndpointImpl endpoint = new EndpointImpl(springBus(), new WeatherImpl());// 绑定要发布的服务实现类endpoint.publish("/weather"); // 接口访问地址return endpoint;}
}
客户端代码的编写:(并未与上述的服务端配对,只是实现思路)
第一、根据CXF客户端生成代码的命令,生成客户端代码。
第二、编写实现类
public class getPhoneAddress{public static String getPhoneMessage(String phone) {//1.生成服务对象MobileCodeWS ms=new MobileCodeWS();//2.创建实现类对象MobileCodeWSSoap port= ms.getPort(MobileCodeWSSoap.class);//3.获取实现方法String msg=port.getMobileCodeInfo("手机号",null);return msg;}