什么是WebService?
一种基于Web的服务,服务端提供一些资源让客户端进行访问,获取一些公共的数据。比如天气预报,股票信息,手机归属地查询等等。
WebService是一种跨平台,跨语言的规范。
气象局负责将收集的每天的天气信息,并将这些信息暴露出来,各大站点的应用去调用网络接口得到当天或者未来几天的天气情况,然后以不同形式展示出来。
网站提供了天气预报的信息,其实网站本身什么都没有做,只是调用了一下远程接口。这个就是WebService的典型应用。
WebService组织图
Web服务的几个重要术语:
WSDL(Web Services Description Language):Web服务描述语言。一个XML文档,WSDL定义了Web Service 的名称、处理服务的方法、请求的参数及返回的数据格式。一个WebService对应唯一一个wsdl文档。
SOAP(Simple Object Access Protocol):简单对象传输协议。一个基于HTTP和XML的协议,用于在Web上的应用程序交换结构化的数据。
SEI(WebService Endpoint Interface):WebService服务端用来处理请求的接口。
CXF(Celtix + XFire):一个Apache的用于开发webService服务器和客户端框架。
WSDL的基本结构:
Types元素
数据类型定义的容器
Message元素
通信消息的数据结构的抽象类型定义
PorType元素
可以描述一个Web Service可被执行的操作以及相关的消息
Binding元素
特定端口类型的具体协议和数据格式规范的绑定
Service元素
相关服务访问点的集合
SOAP概述:
SOAP(SImple Object Access Protocol,简称对象访问协议)基于XML的,用于在分布式环境下交换信息的轻量级协议。
SOAP 1.2规范与2003年6月24日被发布为W3C推荐标准
SOAP的优点
与厂商无关
相对于平台独立
相对与操作系统独立
相对与编程语言独立
开发WebService:
WebService组成
服务器端:提供WebService的服务器端。(Java开发)
客户端:调用远程WebServiec的客户端应用程序。可以在任何系统下使用任何语言调用。
开发WebService分为两种方式
JAX-WS方式:Web标准服务
CXF方式:基于CXF框架开发
JAX-WS方式开发WebService:
开发步骤:
创建一个JavaProject项目
添加WebService的接口,使用@WebService和@WebMethod注解修饰类。
添加实现WebService接口的类,使用@WebService修饰,并指定EndpointInterface属性到接口的完整类名。
添加一个Endpoint来发布WebService。
package com.webservice.server; import java.util.List; import java.util.Set; import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface WeatherService { @WebMethod public Set<String> getProvinces(); @WebMethod public List<String> getCitys(String proName); }
package com.webservice.server; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.jws.WebService; @WebService(endpointInterface="com.webservice.server.WeatherService") public class WeatherServiceImpl implements WeatherService { private static Map<String, ArrayList<String>> provincies; static{ provincies = new HashMap<String, ArrayList<String>>(); ArrayList<String> beijing = new ArrayList<>(); beijing.add("海淀区"); beijing.add("朝阳区"); provincies.put("北京", beijing); ArrayList<String> guangdong = new ArrayList<>(); guangdong.add("广州"); guangdong.add("深圳"); guangdong.add("东莞"); provincies.put("广东省", guangdong); ArrayList<String> hunan = new ArrayList<>(); hunan.add("长沙"); hunan.add("永州"); provincies.put("湖南省", hunan); } @Override public Set<String> getProvinces() { return provincies.keySet(); } @Override public List<String> getCitys(String proName) { return provincies.get(proName); } }
package com.webservice.server.test; import javax.xml.ws.Endpoint; import com.webservice.server.WeatherServiceImpl; public class TestWebService { public static void main(String[] args) { String address = "http://localhost:9999/weather/getweathers"; //发布webService Endpoint.publish(address, new WeatherServiceImpl()); System.out.println("发布成功!"); } }
WebService常用注解:
@WebService(必须的)
修饰一个类或者接口为一个WebSevice,如果有接口,必须提供endpointInterface指定接口名称,否则会报警告。
@WebMethod(可省略)
修饰一个方法为一个Web方法。可以被远程调用。也可以通过exclude=true来排除某个方法。
@WebParm(可省略)
修饰生成wsdl文件中方法的参数名称。
现在我们已经发布了WebService那么怎么调用它呢?
首先我们进入cmd 然后进入到项目中src文件夹中使用wsimport工具从WSDL文件生成客户端调用所需的Java类。
wsimport是JDK中bin中所带的工具,所以需要配置环境变量
G:\daima\上课代码\webService\webServiceClient\src>wsimport -p com.webservice.demo1 -keep http://localhost:9999/weather/getweathers?wsdl
com.webservice.demo1 是我们指定生成的包名。http://localhost:9999/weather/getweathers?wsdl发布的地址
生成之后就是这个样子的,我们刷新eclipse中的项目发现多了一个包
这个玩意就是刚才生成的,那么我们怎么使用呢?
WeatherService weatherService = new WeatherServiceImplService().getWeatherServiceImplPort(); List<String> lists = weatherService.getProvinces();
在网上已经有人家提供的接口我们直接可以调用,当我们JAVA调用的时候遇见.net的怎么解决呢。
首先我们将他接口中的wsdl那些xml保存到本地的src然后我们需要将xml中的
<s:element ref="s:schama" /> <s:any />
改成
<s:any minOccurs="2" maxOccurs="2" />
然后直接调用本地文件生成JAVA文件即可
G:\daima\上课代码\webService\webServiceClient\src>wsimport -p . -keep G:\daima\上课代码\webService\webServiceClient\src\weather.wsdl
p后面那个点指的是根据源文件生成包名。
Apche CXF WebService框架
CXF是apache旗下的开源框架,由Celtix + XFire这两门经典的框架合成,是一套非常流行的web service框架。
CXF的官方网站:
http://cxf.apache.org/download.html
它提供了对JAX-WS的全面支持,只需要拷入jar包即可,不需要任何改动,同时它能与spring进行完美结合。
实际的应用场景中,通常采用更为专业的Java EE应用服务器来发布Web服务。
CXF是流行的Web服务开发框架之一,代表着Celtix和Xfire项目的合并
我们导入所有的jar包需要排除:geronimo-servlet_3.0_spec-1.0.jar,javax.servlet-api-3.1.0.jar。这个在我们tomcat中已经有了,重复会导致冲突
我们首先在web.xml中配置
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springws.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class> org.apache.cxf.transport.servlet.CXFServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
我们发布的时候还是可以和以前一样创建WebService接口,与WebService实体类。
然后就是配置我们的spring文件配置,你会发现多了写不是spring里面的头文件,这是WXF中提供的。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <!-- 在CXF3.0之后不需要下面这两个,不然会报错 --> <!-- <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> --> </beans>
然后我们有两种方式配置
<!-- 第一种配置方式 --> <bean id="weatherService" class="com.webservice.server.WeatherServiceImpl" /> <jaxws:endpoint id="wsServiceBean" implementor="#weatherService" address="/getWeather" publish="true" /> <!-- 第二种配置方式 --> <jaxws:server serviceClass="com.webservice.server.WeatherServiceImpl" address="/getWeather" />
然后我们直接跑这个项目,我们不需要添加任何的页面,它自己会生成页面但是我们会报404的错误,因为在web配置中你直接访问项目会默认查询index.html,index.jsp等这也默认访问的页面。我们可以下连接下访问路径services,这个路径是我们在web.xml中配置的路径。访问:http://localhost:8080/SpringCXF/services,然后我们会看到如下页面:
在spring配置中address就是路径名,可以在图片上清晰看到。publish是决定是否发布。我们可以去调用WSDL接口
使用CXF调用服务:
在CXF中也给我们提供了一种生成方式在我们官方下载的CXF解压出来有个bin目录
我们需要为它配置环境变量然后调用wsdl2java来生成使用起来都是差不多的。
JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean(); bean.setServiceClass(WeatherService.class); bean.setAddress("http://localhost:8080/SpringCxfServer/services/getWeather?wsdl"); WeatherService service = (WeatherService) bean.create(); System.out.println(service.getProvince());
基于json的web服务:
早期webservice是基于xml格式的,具有良好的跨平台性和跨语言性。但是由于这几年json格式的兴起,json是同样也具备跨语言和跨平台性,并且格式更加简洁。所以这几年基于json格式的web服务也越来越流行。
基于json的服务提供商。
百度 appstore
聚合数据
这些很多都是收费的,不过使用起来并不难,提供里面会有调用方式。