常见的WEB服务
- 京东、淘宝
- 天气预报
- 手机号归属地
- 股票查询
一、WebService是什么
- 简介
WebService就是一种跨编程语言、跨系统平台的远程调用技术
。所谓跨编程语言和跨系统平台
就是说服务端程序采用java编写,客户端程序可以采用其他编程语言编写,反之亦然。跨操作平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。远程调用
,一台计算机的应用可以调用其他计算机上的应用。例如:支付宝,支付宝并没有银行卡等数据,它只是去调用银行提供的接口来获得数据。还有天气预报等,也是气象局把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能。 - WebService中的几个重要术语
- WSDL:web service definition language (webservice 定义语言)
定义了web service的服务器端与客户端应用交互传递消息请求和响应数据的格式和方式,一个web service对应一个唯一的wsdl文档 - SOAP:simple object access protocal (简单对象访问协议)
是一种简单的、基于HTTP和XML的协议,用于在WEB上交换结构化的数据,soap消息:请求消息和响应消息 http + xml片段 - SEI: WebService EndPoint Interface(WebService终端接口)
- CXF:Celtix + XFire
一个apache的用于开发开发webservice服务器端和客户端的框架
- 原理
XML,SOAP和WSDL就是构成WebService平台的三大技术 。
- WebService采用Http协议来在客户端和服务端之间传输数据。WebService使用XML来封装数据,XML主要的优点在于它是跨平台的。
WebService
通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML
格式封装,并增加了一些特定的HTTP消息头
,以说明HTTP消息的内容格式,这些特定的HTTP
消息头和XML
内容格式就是SOAP(Simple Object Access Protocol 简单对象访问协议)协议
规定的。WebService
服务器首先要通过一个WSDL
文件来说明自己有什么服务可以对外调用。简单的说WSDL
就像一个说明书,用于描述WebService即其方法、参数和返回值
。WSDL
文件保存在Web服务器上,通过一个url
地址就可以访问它。客户端要调用一个WebService
服务之前,要知道该服务的WSDL
文件的地址。WebService
服务提供商可以通过两种方式来暴露它的wsdl文件地址:1.注册到UDDI服务器,以便人查找;2.直接告诉给客户端调用者。
- 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 通过集成CXF实现
- 服务端
- WeatherService
package service;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface WeatherService {
public String getCityInfo(@WebParam(name = "cityName") String cityName);
}
- WeatherServiceImpl
package service.impl;
import service.WeatherService;
public class WeatherServiceImpl implements WeatherService {
@Override
public String getCityInfo(String cityName) {
String res = "";
if (cityName.equals("北京")) {
res = cityName + ":大雨";
}
if (cityName.equals("上海")) {
res = cityName + ":多云";
}
return res;
}
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<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:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
</beans>
- cxf.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<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:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<!-- comment this bean to disable schema validation in the client -->
<!-- <jaxws:client name="{http://apache.org/hello_world_soap_http}SoapPort"
createdFromAPI="true">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:client>
<jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort"
wsdlLocation="wsdl/hello_world.wsdl"
createdFromAPI="true">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint> -->
<!-- 服务类,将服务类注入到spring容器 -->
<bean id="weather" class="service.impl.WeatherServiceImpl"></bean>
<!-- 将服务发布 -->
<jaxws:server address="/weather">
<jaxws:serviceBean>
<ref bean="weather"/>
</jaxws:serviceBean>
</jaxws:server>
</beans>
- 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>webservice01</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>
<!--加载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>
<init-param>
<param-name>config-location</param-name>
<param-value>classpath:cxf.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
注意路径为/ws/*不是/ws
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
</web-app>
- pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cjw</groupId>
<artifactId>webservice06</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<webVersion>3.0</webVersion>
<spring.version>3.2.17.RELEASE</spring.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
- 项目启动
- 点击项目右键
- 输入tomcat7:run,确定即可
测试结果:
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.service/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://service/" name="WeatherServiceImplService" targetNamespace="http://impl.service/">
<wsdl:import location="http://localhost:8080/ws/weather?wsdl=WeatherService.wsdl" namespace="http://service/"> </wsdl:import>
<wsdl:binding name="WeatherServiceImplServiceSoapBinding" type="ns1:WeatherService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getCityInfo">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getCityInfo">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getCityInfoResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WeatherServiceImplService">
<wsdl:port binding="tns:WeatherServiceImplServiceSoapBinding" name="WeatherServiceImplPort">
<soap:address location="http://localhost:8080/ws/weather"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
问题:如果按照下图配置会出现
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<!-- <url-pattern>/ws/*</url-pattern> -->
<url-pattern>/ws</url-pattern>
</servlet-mapping>
- 客户端
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class client {
public static void main(String[] args) {
// 1、本地代理工厂实例
JaxWsProxyFactoryBean pf = new JaxWsProxyFactoryBean();
// 2、设置webservice服务端的地址,加上wsdl也可以
pf.setAddress("http://localhost:8080/ws/weather?wsdl");
// 3、创建的到本地代理类(桩)
/*
* service.impl.WeatherServiceImpl is not an interface
* pf.create参数应该为接口
* */
WeatherService address = pf.create(WeatherService.class);
String result = address.getCityInfo("北京");
System.out.println(result);
}
}
测试结果:
三、使用JDK开发WebService
- 开发服务端
- Web Service编码
@WebService(SEI和SEI的实现类)
@WebMethod(SEI中所有方法)
- 发布WebService
Endpoint(终端,发布webservice)
- 具体实现
- HelloWS
package com.atguigu.day01ws.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
/*
* SEI:webservice 接口
*/
@WebService
public interface HelloWS {
/**
*
* @param name
* @return
*/
@WebMethod
public String sayHello(String name);
}
- HelloWsImpl
package com.atguigu.day01ws.ws;
import javax.jws.WebService;
@WebService
public class HelloWsImpl implements HelloWS {
@Override
public String sayHello(String name) {
// TODO Auto-generated method stub
System.out.println("wevservice...." + name);
return "Hello " + name;
}
}
- ServerTest
package com.atguigu.day01ws.ws.server;
import javax.xml.ws.Endpoint;
import com.atguigu.day01ws.ws.HelloWsImpl;
/**
* 发布WebService
* @author 淘小子
*/
public class ServerTest {
public static void main(String[] args) {
/**
* EndPoint
*/
String address = "http://localhost:8080/webserviceJdk/hellows";
Endpoint.publish(address, new HelloWsImpl());
System.out.println("发布webserviceImpl成功");
}
}
- 创建客户端应用编码方式访问
wsimport.exe使用
wsimport -keep url
wsimport -keep http://localhost:8080/webserviceJdk/hellows?wsdl
四、webservice和http的区别
- 基于不同协议:
HTTPService
基于http
协议,而WebService
基于soap
协议; - 处理数据效率不同:
HTTPService
效率较高,WebService
能处理较复杂的数据类型。
http
协议支持客户/服务器模式,简单快速,客户向服务器请求服务时,只需传送请求方法和路径灵活,http
允许传输任意类型的数据对象。无连接,即限制每次连接只处理一个请求,可以节省传输时间。 - 跨域的处理:
HttpService
方式不能处理跨域,如果调用一个其它应用的服务就要用webService
简单说httpservice
通过post
和get
得到你想要的东西webservice
就是使用soap
协议得到你想要的东西,相比httpservice
能处理些更加复杂的数据类型。当你要调用一个你本服务的内容的时候,不涉及到跨域的问题,你可以使用HttpService
的方式。如果,你需要在后台调用一个其它应用的服务,这个时候,你必须要用webService
的方式来调用。