WebService
简介:
简单来说就是一个我们可以自定义需要发布的服务来供其它客户端来调用的一种模式 他分为两个部分一个为服务端一个为客户端 服务端是用来写我们的需要调什么的服务 客户端就是我们具体的需求通过调用服务端的方法来接收返回值的一种模式
特点:
概括来说三种:
1.跨语言 2.跨平台 3.远程调用
缺点:
由于他的数据是采用XML来传输的所以解析时需要时间所以性能不是很高
建议使用的场景:
1.不考虑客户端的类型
2.远程调用的场景
3.不考虑性能
不建议使用的场景:
1.性能要求较高的
2.同构程序
WebService三要素
1.SOAP: 协议
2.WSDL:使用手册---里面可以查看我们的服务到底有什么 以及服务自定义的方法以及方法的参数都可以看见
swdl的主要结构(xml格式的):
<service>
服务视图,WebService的服务端点
<binding>
Web Services的通信协议,还描述Web Services的方法、输入、输出。
<portType>
描述了WebService可执行的操作,通过binding指向portType
<message>
描述了服务中发布的方法,包括参数,返回值等。
<types>
定义了WebService中使用的数据类型
3.UDDL:目录---跨产业跨平台的开放性架构
=====================================================================================================================================
自定义发布服务:
我们以自定义查询天气的来举例
首先定义一个查询天气的接口
public interface IWeatherService {
public String queryWeather(String cityName);
}
然后自定义一个类实现这个接口 注意这边实现这个接口的时候需要加上 注解 @WebService表明当前类为实现类
@WebMethod(exclude=true)方法上面添该注解表示不发布这个方法
public class WeatherServiceImpl implements IWeatherService {
public String queryWeather(String cityName) {
System.out.println("WeatherServiceImpl.queryWeather() " + cityName);
return "大晴天";
}
}
然后自定义发布的方法里面写main方法 发布
通过
参数一:发布的服务地址
参数二:自定义的实现类
Endpoint.publish("http://localhost:8080/weatherService", new WeatherServiceImpl());
这样就可以查看一个服务端是否发布成功了
如果输入服务地址如下图所示一个简单的服务就发布成功了 我们可以在服务的地址后面加上 ?wsdl来查看他的使用手册 或者说是WSDL
客户端:
首先要生成服务端代码:
在cmd环境下 进入自己项目的路径下然后 通过wsimport -s 服务的路径 http://127.0.0.1:8088/weather?wsdl(或者是自己下载下来的xml文件路径) -p 自定义包名 也可以不指定就是默认的
然后就是自定义类进行客户端的调用
方法一:缺点--服务地址写死 不灵活 只要发布的服务改变地址就需要重新获取客户端代码
1.创建服务试图 (wsdl里面的service标签的name 属性 )
WeacherServiceImplService serviceImpl=new WeacherServiceImplService();
2.获取服务视图的实现类(wsdl里面的porttype标签的 name 属性)
WeacherServiceImpl service = serviceImpl.getPort(WeacherServiceImpl.class);
3.调用方法:
String result = service.queryWeather("吉首");
4.输出结果
方法二:
1.设置服务端地址
URL url = new URL("http://localhost:8080/weatherService?wsdl");
2.设置Qname(参数一 wsdl的命名空间 wsdl 里面的 targetNamespace 属性的值 参数二 服务视图的名称 service的name属性)
QName qName = new QName("http://impl.service.qf.com/", "WeatherServiceImplService");
3.创建服务试图
Service service = Service.create(url, qName);
4.得到服务视图的实现类(wsdl里面的porttype标签的 name 属性)
WeatherServiceImpl weatherServiceImpl = service.getPort(WeatherServiceImpl.class);
5.调用方法
String result = weatherServiceImpl.queryWeather("青海");
方法三: --这种方法不需要生成客户端代码 但是要模拟XML的提交方式(重点掌握第二种)
利用CXF发布和调用服务:
Cxf:是一个开源的WebService的框架 他支持的格式有 XML 和 JsON
环境搭建:
1.将下载的文件进行解压,配置环境变量,新建CXF_HOME,输入下载文件库的路径,
示例:C:\software\apache-cxf-3.2.1\apache-cxf-2.7.11
2.在系统环境变量的Path追加%CXF_HOME%\bin
3.测试,在cmd下加入wsdl2java
服务端:
自定义接口 --- 注意这边的话不像上面那种模式把注解加载实现类上这种需要加到接口上 @WebService
实现类
然后发布服务:(使用jaws 发布服务)
1.首先获得工厂
JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
2.设置他的服务地址
jaxWsServerFactoryBean.setAddress("http://localhost:8080/WeatherService");
3.设置服务的接口
jaxWsServerFactoryBean.setServiceClass(IWeatherService.class);
4.设置服务的实现类
jaxWsServerFactoryBean.setServiceBean(new WeatherServiceImpl());
5.发布
jaxWsServerFactoryBean.create();
客户端 :
首先也和上面一样先是获得服务端的代码
wsdl2java常用参数:
-d,指定输出目录
-p,指定包名,如果不指定该参数,默认包名是WSDL的命名空间的倒序
客户端调用:
1.获得工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
2.设置服务的接口(portType 里面的name 属性)
jaxWsProxyFactoryBean.setServiceClass(IWeatherService.class);
3.设置地址
jaxWsProxyFactoryBean.setAddress("http://localhost:8080/WeatherService");
4.获取服务接口的实例 (将获得的对象转换成实现的接口类型)
IWeatherService weatherService = (IWeatherService)jaxWsProxyFactoryBean.create();
5.方法调用;
String result = weatherService.queryWeacher("深圳");
Cxf发布webservice:
JaxWsServerFactoryBean:发布webservice服务
JaxWsProxyFactoryBean:调用webservice服务
CXF整合Spring (配置方式)加入相关的约束条件
发布服务:使用spring和cxf整合的标签<jaxws:server >
1.创建SEI接口 WebService的终端接口 也就是上面的自定义接口
2.创建实现类
3.配置applicationContext.xml文件
a)加入相关的约束
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
b)利用bean 实例化服务实现类
<!-- 服务实现类 -->
<bean id="weatherServiceImpl" class="com.qf.service.impl.WeatherServiceImpl"/>
c) <!-- 利用jaxws:server发布服务端
address:服务地址
serviceClass:服务接口的全类名
-->
<jaxws:server address="/WeatherService" serviceClass="com.qf.service.IWeatherService">
<jaxws:serviceBean>
<!-- 引入服务的实现类 -->
<ref bean="weatherServiceImpl"/>
</jaxws:serviceBean>
</jaxws:server>
4.配置web.xml自动开启ToCat的时候开启Spring
5.配置CXF的Servlet用于解析CXF发布的webService
第六步:启动tomcat,部署web工程到tomcat**
第七步:测试服务是否发布成功**
WSDL地址规则:http://localhost:端口号/项目名称/servlet拦截路径/服务名称?wsdl
客户端调用服务:使用spring和cxf整合的标签<jaxws:client>
‘ 1.成服务端代码
2.配置Spring
<!--
使用jaxws:client调用服务端
serviceClass:设置服务接口(客户端生成的服务接口)
address:服务地址
-->
<jaxws:client id="weatherClient" serviceClass="com.qf.springcxf.IWeatherService"
address="http://localhost:8080/cxf_webservice01/ws/WeatherService?wsdl">
</jaxws:client>
然后后面就可以获取这个实例化的id 获取实例进行方法的调用了
也可以简单的使用注解的方式获取‘
先自动注入
然后调用方法:
CXF发布restFul风格的服务
restFul
--资源定位(url)
--资源的操作
GET、POST、PUT、DELETE
发布服务 以查询学生的信息举例
1.首先创建学生的实体类 并在实体类上加上注解
@XmlRootElement(name="student") //@XmlRootElement可以实现对象和XML数据之间的转换
2.创建接口(重要)
3.实现类
5.发布:
1.编程式发布:JAXRSServerFactoryBean
1.获得发布的工厂
JAXRSServerFactoryBean jaxrsServerFactoryBean = new JAXRSServerFactoryBean();
2.设置服务地址
jaxrsServerFactoryBean.setAddress("http://localhost:8080/studentServie");
3.设置服务的实现类
jaxrsServerFactoryBean.setServiceBean(new StudentServiceImpl());
4.设置资源对象如果多个资源用, 隔开(创建的实体类)
jaxrsServerFactoryBean.setResourceClasses(Student.class);
5.发布
jaxrsServerFactoryBean.create();
-----------------发布后的查看地址为 xxxxx?_wadl
2.配置Spring方式的方式发布
<!-- 配置的方式发布Rest服务 -->
<!-- 服务实现类 -->
<bean id="studentServiceImpl" class="com.qf.service.impl.StudentServiceImpl"/>
<!--
address:服务地址
-->
<jaxrs:server address="/studentService" >
<jaxrs:serviceBeans>
<ref bean="studentServiceImpl"/>
</jaxrs:serviceBeans>
</jaxrs:server>
客户端调用:
1 .编程方式:
在地址栏输入需要查询的方法以及参数