在本文中,我们将为您详细介绍WebService-RESTful和SOAP笔记的相关知识,并且为您解答关于soaprestfulwebservice区别的疑问,此外,我们还会提供一些关于CXF结合sp
在本文中,我们将为您详细介绍Web Service - RESTful 和 SOAP 笔记的相关知识,并且为您解答关于soap restful webservice 区别的疑问,此外,我们还会提供一些关于CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services、java – SOAP webservice和RESTFUL webservice之间的区别、restful webservice SOAP webservice、RESTful Webservice 和 SOAP Webserivce 对比及区别的有用信息。
本文目录一览:- Web Service - RESTful 和 SOAP 笔记(soap restful webservice 区别)
- CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services
- java – SOAP webservice和RESTFUL webservice之间的区别
- restful webservice SOAP webservice
- RESTful Webservice 和 SOAP Webserivce 对比及区别
Web Service - RESTful 和 SOAP 笔记(soap restful webservice 区别)
1.什么是Web Service(Web服务)
从表面上看,Web Service就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。
这就是说,你能够用编程的方法透明的调用这个应用程序,不需要了解 它的任何细节,
跟你使用的编程语言也没有关系。
例如可以创建一个提供天气预报的Web Service,那么无论你用哪种编程语言开发的应用,都可以通过调用它的API并传入城市信息来获得该城市的天气预报。
之所以称之为Web Service,是因为它基于HTTP协议传输数据,
这使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件,
就可相互交换数据或集 成。
2.SOA(Service-Oriented Architecture,面向服务的架构)
SOA是一种思想,它将应用程序的不同功能单元通过中立的契约联系起来,
独立于硬件平台、操作系统和编程语言,使得各种形式的功能单元能够更好的集成。
显然,Web Service是SOA的一种较好的解决方案,它更多的是一种标准,而不是一种具体的技术。
3.概念解释:SOAP、WSDL、UDDI
SOAP |
简单对象访问协议(Simple Object Access Protocol), 是Web Service中交换数据的一种协议规范。 |
WSDL |
Web服务描述语言(Web Service Description Language), 它描述了Web服务的公共接口。 这是一个基于XML的关于如何与Web服务通讯和使用的服务描述; 也就是描述与目录中列出的Web服 务进行交互时需要绑定的协议和信息格式。 通常采用抽象语言描述该服务支持的操作和信息, 使用的时候再将实际的网络协议和信息格式绑定给该服务。 |
UDDI |
统一描述、发现和集成(Universal Description, Discovery and Integration), 它是一个基于XML的跨平台的描述规范, 可以使世界范围内的企业在互联网上发布自己所提供的服务。 简单的说,UDDI是访问各 种WSDL的一个门面(可以参考设计模式中的门面模式)。 |
4.Java规范中和Web Service相关的规范有哪些
Java规范中和Web Service相关的有三个
JAX-WS(JSR 224) |
这个规范是早期的基于SOAP的Web Service规范JAX-RPC的替代版本, 它并不提供向下兼容性, 因为RPC样式的WSDL以及相关的API已经在Java EE5中被移除了。 WS-MetaData是JAX-WS的依赖规范, 提供了基于注解配置Web Service和SOAP消息的相关API。 |
JAXM(JSR 67) |
定义了发送和接收消息所需的API,相当于Web Service的服务器端 |
JAX-RS(JSR 311 & JSR 339 & JSR 370) |
是针对REST(Representation State Transfer)架构风格制定的一套Web Service规范。 它不像SOAP那样本身承载着一种消息协议, 可以将REST视为基于HTTP协议的软件架构。 REST中最重要的两个概念是资源定位和资源操作, 而HTTP协议恰好完整的提供了这两个点。 HTTP协议中的URI可以完成资源定位, 而GET、POST、OPTION、DELETE方法可以完成资源操作。 而不像SOAP协议那样只利用了HTTP的传输特性, 定位和操作都是由SOAP协议自身完成的, 也正是由于SOAP消息的存在使得基于SOAP的Web Service显得笨重逐渐被淘汰。 |
5.REST和SOAP Web Service的比较
5.1什么是SOAP?
SOAP (Simple Object Access Protocol) 顾名思义,是一个严格定义的信息交换协议,
用于在Web Service中,把远程调用和返回封装成机器可读的格式化数据。
事实上SOAP数据使用XML数据格式,
定义了一整套复杂的标签,以描述调用的远程过程、参数、返回值和出错信息等等。
而且随着需要的增长,又不得增加协议以支持安全性,
这使SOAP变得异常庞大,背离了简单的初衷。
另一方面,各个服务器都可以基于这个协议推出自己的API,
即使它们提供的服务及其相似,定义的API也不尽相同,这又导致了WSDL的诞生。
WSDL (Web Service Description Language) 也遵循XML格式,
用来描述哪个服务器提供什么服务,怎样找到它,以及该服务使用怎样的接口规范,
简言之,服务发现。
现在,使用Web Service的过程变成,
获得该服务的WSDL描述,
根据WSDL构造一条格式化的SOAP请求发送给服务器,
然后接收一条同样SOAP格式的应答,
最后根据先前的WSDL解码数据。
绝大多数情况下,请求和应答使用HTTP协议传输,那么发送请求就使用HTTP的POST方法。
5.2什么是REST?
REST (REpresentational State Transfort),
形式上应该表述为客户端通过申请资源来实现状态的转换,
在这个角度,系统可以看成一台虚拟的状态机。
REST应该满足这样的特点:
1)客户端和服务器结构;
2)连接协议具有无状态性;
3)能够利用Cache机制增进性能;
4)层次化的系统;
5)按需代码。
说到底,REST只是一种架构风格,而不是协议或标准。
但这种风格对现有的以SOAP为代表的Web Service造成的冲击也是革命性的,
因为它面向资源,甚至连服务也抽象成资源,
因为它和HTTP紧密结合,因为它服务器无状态。
5.3REST与SOAP的区别?
即使绝大多数SOAP是运行在HTTP上,使用URI标识服务,
SOAP也仅仅使用POST方法发送请求,用一个唯一的URI标识服务的入口。
对于SOAP,delete操作也要用POST方法来发送,
而其实HTTP协议有更合逻辑的DELETE方法可用。
REST为每一个资源指定一个唯一的URI,
而用HTTP的4种方法GET、POST、PUT、DELETE直观地表示
获取、创建、更新和删除图书。
REST的优点?
REST简单而直观,把HTTP协议利用到了极限。
1. 它用HTTP请求的头信息来指明资源的表示形式,
2. 用HTTP的错误机制来返回访问资源的错误。
由此带来的直接好处是构建的成本减少了,
例如用URI定位每一个资源可以利用通用成熟的技术,
而不用再在服务器端开发一套资源访问机制。
3. 只需简单配置服务器就能规定资源的访问权限,
例如通过禁止非GET访问把资源设成只读。
4. 服务器无状态带来了更多额外好处,
因为每次请求都包含响应需要的所有信息,所有状态信息都存储在客户端,
服务器的内存从庞大的状态信息中解放出来。
而且现在即使一台服务器突然死机对客户的影响也微乎其微,
因为另一台服务器可以马上代替它的位置,而不需要考虑恢复状态信息。
5. 更多的缓存也变成可能,
而之前由于服务器有状态,对同一个URI的请求可能导致完全不同的响应。
总体结果是,网络的容错性和延展性都增强了,这些本来是WEB设计的初衷,
日趋复杂和定制的WEB把它们破坏了,现在REST又返璞归真,
试图把Web Service带回简单的原则中来。
REST的不足之处?
无状态带来了巨大的优势,同时也带来了难以解决的问题,
例如,怎样授权特定用户才能使用的服务?怎样验证用户身份?
如果坚持服务器无状态,也就是不记录用户登录状态,
势必要求每一次服务请求都包含完整的用户身份和验证信息。
在这种情况下,怎样避免冒认?怎样避免用户信息泄漏?
事实上,构建REST附属的安 全机制已经在讨论中,
其结果无非导致另一个SOAP:复杂的需求摧残了易用性。
REST在面向资源的应用中左右逢源,但在面向事务的应用中却未如人意。
面向资源的应用操作简单,无非创建、读取、改变、删除几项,
但是面向事务的应用不允许用户直接操作资源,
用户只需向系统提交一个事务说明要求,然后等待事 务的完成,
就如一个网上银行的用户不直接修改账户和存款,
而是提交一个事务告诉银行自己要转账。
如果把这样的服务看成一种资源,
通过向资源发送POST请 求完成事务,那不过是SOAP的翻版而已。
无论是这样,还是通过PUT来创建事务,
都改变了系统的状态(资源本身未改变,此处是改变了用户的余额),
显然 违背了REST直观的初衷。
CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services
CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services
1、访问:http://localhost:8088/sniperWS/services/
查看有哪些服务,包含 Available SOAP services、Available RESTful services
2、客户端调用 RESTful services:
http://localhost:8088/sniperWS/services/address/getSuggestions.query
调用示例:
$.ajax({
url: "http://ip:port/sniperWS/services/address/getSuggestions.query",
dataType: "json",
data : {
"address" : '' 罗湖 '',
"max":10,
"_type":"json"
},
cache : false,
success: function(data) {
var items = data.addressVO;
for(var index in items) {
alert(items[index].address);
}
},
error : function(error) {
alert(error);
}
});
ws-services-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
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/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd" default-autowire="byName">
<!--spring发布web服务配置 -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="addressService" class="cn.sniper.ws.service.AddressServiceImpl" />
<!-- 方式一:发布SOAP services -->
<!-- <jaxws:endpoint id="addressWS" implementor="#addressService" address="/addressWS" /> -->
<!-- 方式二:发布SOAP services -->
<jaxws:server id="addressWS" address="/addressWS">
<jaxws:serviceBean>
<ref bean="addressService" />
</jaxws:serviceBean>
<!-- <jaxws:inInterceptors>
<bean ></bean>
</jaxws:inInterceptors> -->
</jaxws:server>
<!-- 发布RESTful services-->
<jaxrs:server id="addressServiceWS" address="/address">
<jaxrs:extensionMappings>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>
<jaxrs:serviceBeans>
<ref bean="addressService" />
</jaxrs:serviceBeans>
<!-- <jaxrs:inInterceptors>
<bean ></bean>
</jaxrs:inInterceptors> -->
</jaxrs:server>
</beans>
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=
xmlns:xsi=
xmlns:context=
xmlns:aop=
xmlns:tx=
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.sniper.ws.service"></context:component-scan>
<import resource="ws-services-context.xml"/>
</beans>
AddressService
package cn.sniper.ws.service;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import cn.sniper.ws.po.Address;
@SOAPBinding(style = Style.DOCUMENT)
@WebService(targetNamespace = "http://cn.sniper.ws.service")
public interface AddressService {
public List<Address> getSuggestions(@WebParam(name="address")String address, @WebParam(name="max")int max);
}
AddressServiceImpl
package cn.sniper.ws.service;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import cn.sniper.ws.po.Address;
@Path(value="/")
@SOAPBinding(style = Style.DOCUMENT)
@WebService(
serviceName = "address",
portName = "address",
targetNamespace = "http://cn.sniper.ws.service",
endpointInterface = "cn.sniper.ws.service.AddressService")
public class AddressServiceImpl implements AddressService {
@GET
@Path("getSuggestions.query")
public List<Address> getSuggestions(@QueryParam("address")String address, @QueryParam("max")int max) {
List<Address> addressList = new ArrayList<Address>();
addressList.add(new Address(1L, "admin-1"));
addressList.add(new Address(2L, "admin-2"));
return addressList;
}
}
Address
package cn.sniper.ws.po;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* 注意,@XmlRootElement(name="addressVO")的name不要和属性的name重复,
* 否则会导xml解析过程报错
* @author audaque
*
*/
@XmlRootElement(name="addressVO")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"id","address"})
public class Address implements Serializable {
private static final long serialVersionUID = -1704617795954765535L;
@XmlElement(name="id")
private Long id;
@XmlElement(name="address")
private String address;
public Address() {
}
public Address(Long id, String address) {
this.id = id;
this.address = address;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!-- 通过上下文参数指定spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/beans.xml</param-value>
</context-param>
<!-- spring上下文载入器监听器,确保web服务器启动时,完成spring容器的初始化 ,放在了application范围中-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- cxf -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.sniper.ws</groupId>
<artifactId>sniperWS</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>sniperWS Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.1.1.RELEASE</spring.version>
<struts.version>2.3.4.1</struts.version>
<hibernate.version>3.6.9.Final</hibernate.version>
<junit.version>4.8.1</junit.version>
</properties>
<dependencies>
<!-- spring配置 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</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-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-oxm</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-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 注解拦截,需要引入spring aop相关jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</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-hibernate3</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- aspectj -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.6.2</version>
</dependency>
<!-- @ResponseBody 将数据转换成json的依赖包,如果没有依赖包,即使能够访问action,返回的时候也会报错 -->
<!-- 解决:Could not find acceptable representation报错; 客户端报错:ajax not acceptable -->
<!-- <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency> -->
<!-- cxf -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>apache-cxf</artifactId>
<version>2.6.1</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.2.3</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>sniperWS</finalName>
</build>
</project>
java – SOAP webservice和RESTFUL webservice之间的区别
> SOAP Webservice.
> RESTful Webservice.
任何人都可以告诉我它们之间的基本区别是什么.在哪种情况下创建SOAP Web服务以及在哪种情况下创建RESTful Webservice.
谢谢,
解决方法
肥皂:
>您在.wsdl文件中定义接口,该文件准确描述了预期的输入参数以及返回值的外观
>有些工具可以用java类hirarchies生成.wsdl文件. JAXB for example
>还有一些工具可以生成java对象/类作为eclipse的一部分(例如暂时不知道名称).
> SOAP非常严格.在处理之前,每个请求都是针对wsdl进行验证的.
从SOAP WS框架开始,一个好但不那么容易的是Apache CXF
REST(到目前为止没有亲身体验,随时纠正和改进;)):
>访问Web服务器或Web应用程序以从中检索数据或向其发送数据的方法.
>它只是协商,如何访问.
> common就是这个http://server.domain.com/app/type/id=123,用于检索id = 123的类型类型的对象
>非常直观,但没有自动验证请求.
> ……
我相信,我错过了其他几点.但我认为这是一个有用的开始.
restful webservice SOAP webservice
为了说明这个问题,必须的纠正一下我们对 HTTP 的认识。
首先回顾一下 OSI 七层模型
OSI(Open System Interconnection,开放系统互连)七层模型
7 应用层
6 表示层
5 会话层
4 传输层
3 网络层
2 数据链路层
1 物理层
HTTP 并不是一种传输层的 “传输协议”(第四层),而是一种应用层的 “转移协议”(最高层)。
SOAP 类型的 WebService 就是最好的例子,SOAP 消息完全就是将 Http 协议作为消息承载,
以至于对于 Http 协议中的各种参数(例如编码,错误码等)都置之不顾。
Rest(Representional state transfer)
其实,它有着非常丰富的语义,Http 协议所抽象的 get,post,put,delete 就好比数据库中最基本的增删改查,而互联网上的各种资源就好比数据库中的记录。
restful webservice
WEB 的在世界范围类的普及和成功,人们从技术角度对它的总结,既 -- 分布式架构,注意强调的是架构风格 - architectural style.
是一种全新的 Web 开发思维方式, 一种基于 Http 协议来资源操作的思想,是基于 URI 来设计系统的架构。
那么它的特点主要由以下五点
1. 面向资源(resource)
2. 每个资源都对应唯一的 URI uniform resource identifier
3. 抽象资源的操作,使用通用连接接口来操作资源 (generic connector interface)
4. 对资源的操作不会改变 URI
5. 所有的操作无状态 (stateless)
可以看出 REST 抽象资源的操作跟 HTTP 不谋而合,将 Http 协议的设计初衷作了诠释。为了包装 RPC (Remote Procedure Call) 的请求信息,推出了 XML-RPC,但 XML-RPC 只能使用有限的数据类型种类和一些简单的数据结构。
SOAP/WSDL webservice
于是就出现了 SOAP
SOAP(Simple Object Access Protocol) 是基于 XML 的结构化数据交换。SOAP 可以和多种传输协议绑定(Binding),如包括超文本传输协议( HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)使用底层协议交换信息,如: HTTP。
理论上,SOAP 就是一段 xml,你可以通过 HTTP,SMTP 等发送它 (复制到软盘上,叫快递公司送去也行)。
SOAP 跟 HTTP 的关系
SOAP 在 HTTP 协议的基础之上,一个基于 XML 的协议。即 HTTP + XML = SOAP 或者说 SOAP 方式是一个遵照 SOAP 编码规则的 HTTP 请求 / 响应。
WSDL
WSDL 是基于 SOAP 通信时的描述语言,WSDL 是用来描述 SOAP 的,也是一段 xml。
那么,我们可以从以下几个方面去比较它们的优劣
1. 成熟,规范
SOAP 比 REST 成熟,规范,受到很多厂商的支持,REST 只是提供了思想,所以大家还处在各自为战的局面。
2. 伸缩性
REST 是基于 HTTP 协议实现资源操作,大大的降低了开发复杂度和伸缩性。
3. 效率,易用
SOAP 根据需求在不断的扩展协议的内容,导致处理性能下降,学习成本上升。而 REST 采用 ROA(Resource-Oriented Architecture,面向资源的体系架构)进行设计并且融合 WEB2.0 前端技术,提高了开发效率。
4. 安全性
SOAP 采用 XML-Security 和 XML-Signature 两个规范组成了 WS-Security 来实现安全控制,REST 目前没有任何说明。
RESTful Webservice 和 SOAP Webserivce 对比及区别
原文:http://www.blogjava.net/diggbag/articles/361703.html
接口抽象
RESTful Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象所有 Web 系统的服务能力,而不同的是,SOAP 应用都通过定义自己个性化的接口方法来抽象 Web 服务,这更像我们经常谈到的 RPC。例如本例中的 getUserList 与 getUserByName 方法。
RESTful Web 服务使用标准的 HTTP 方法优势,从大的方面来讲:标准化的 HTTP 操作方法,结合其他的标准化技术,如 URI,HTML,XML 等,将会极大提高系统与系统之间整合的互操作能力。尤其在 Web 应用领域,RESTful Web 服务所表达的这种抽象能力更加贴近 Web 本身的工作方式,也更加自然。
同时,使用标准 HTTP 方法实现的 RRESTful Web 服务也带来了 HTTP 方法本身的一些优势:
- 无状态性(Stateless)
HTTP 协议从本质上说是一种无状态的协议,客户端发出的 HTTP 请求之间可以相互隔离,不存在相互的状态依赖。基于 HTTP 的 ROA,以非常自然的方式来实现无状态服务请求处理逻辑。对于分布式的应用而言,任意给定的两个服务请求 Request 1 与 Request 2,由于它们之间并没有相互之间的状态依赖,就不需要对它们进行相互协作处理,其结果是:Request 1 与 Request 2 可以在任何的服务器上执行,这样的应用很容易在服务器端支持负载平衡 (load-balance)。
- 安全操作与幂指相等特性(Safety /Idempotence)
HTTP 的 GET、HEAD 请求本质上应该是安全的调用,即:GET、HEAD 调用不会有任何的副作用,不会造成服务器端状态的改变。对于服务器来说,客户端对某一 URI 做 n 次的 GET、HAED 调用,其状态与没有做调用是一样的,不会发生任何的改变。
HTTP 的 PUT、DELTE 调用,具有幂指相等特性,即:客户端对某一 URI 做 n 次的 PUT、DELTE 调用,其效果与做一次的调用是一样的。HTTP 的 GET、HEAD 方法也具有幂指相等特性。
HTTP 这些标准方法在原则上保证你的分布式系统具有这些特性,以帮助构建更加健壮的分布式系统。
安全控制
为了说明问题,基于上面的在线用户管理系统,我们给定以下场景:
参考一开始我们给出的用例图,对于客户端 Client2,我们只希望它能以只读的方式访问 User 和 User List 资源,而 Client1 具有访问所有资源的所有权限。
如何做这样的安全控制?
通行的做法是:所有从客户端 Client2 发出的 HTTP 请求都经过代理服务器 (Proxy Server)。代理服务器制定安全策略:所有经过该代理的访问 User 和 User List 资源的请求只具有读取权限,即:允许 GET/HEAD 操作,而像具有写权限的 PUT/DELTE 是不被允许的。
如果对于 REST,我们看看这样的安全策略是如何部署的。如下图所示:
图 4. REST 与代理服务器 (Proxy Servers)
一般代理服务器的实现根据 (URI,HTTP Method) 两元组来决定 HTTP 请求的安全合法性。
当发现类似于(http://localhost:8182/v1/users/{username},DELETE)这样的请求时,予以拒绝。
对于 SOAP,如果我们想借助于既有的代理服务器进行安全控制,会比较尴尬,如下图:
图 5. SOAP 与代理服务器 (Proxy Servers)
http://localhost:8182/v1/soap/servlet/messagerouter
,HTTP POST)这样的信息,如果代理服务器想知道当前的 HTTP 请求具体做的是什么,必须对 SOAP 的消息体解码,这样的话,意味着要求第三方的代理服务器需要理解当前的 SOAP 消息语义,而这种 SOAP 应用与代理服务器之间的紧耦合关系是不合理的。
关于缓存
众所周知,对于基于网络的分布式应用,网络传输是一个影响应用性能的重要因素。如何使用缓存来节省网络传输带来的开销,这是每一个构建分布式网络应用的开发人员必须考虑的问题。
HTTP 协议带条件的 HTTP GET 请求 (Conditional GET) 被设计用来节省客户端与服务器之间网络传输带来的开销,这也给客户端实现 Cache 机制 ( 包括在客户端与服务器之间的任何代理 ) 提供了可能。HTTP 协议通过 HTTP HEADER 域:If-Modified-Since/Last- Modified,if-none-match/ETag 实现带条件的 GET 请求。
REST 的应用可以充分地挖掘 HTTP 协议对缓存支持的能力。当客户端第一次发送 HTTP GET 请求给服务器获得内容后,该内容可能被缓存服务器 (Cache Server) 缓存。当下一次客户端请求同样的资源时,缓存可以直接给出响应,而不需要请求远程的服务器获得。而这一切对客户端来说都是透明的。
图 6. REST 与缓存服务器 (Cache Server)
使用 HTTP 协议的 SOAP,由于其设计原则上并不像 REST 那样强调与 Web 的工作方式相一致,所以,基于 SOAP 应用很难充分发挥 HTTP 本身的缓存能力。
图 7. SOAP 与缓存服务器 (Cache Server)
其一、所有经过缓存服务器的 SOAP 消息总是 HTTP POST,缓存服务器如果不解码 SOAP 消息体,没法知道该 HTTP 请求是否是想从服务器获得数据。
其二、SOAP 消息所使用的 URI 总是指向 SOAP 的服务器,如本文例子中的 http://localhost:8182/v1/soap/servlet/messagerouter
,这并没有表达真实的资源 URI,其结果是缓存服务器根本不知道那个资源正在被请求,更不用谈进行缓存处理。
关于连接性
在一个纯的 SOAP 应用中,URI 本质上除了用来指示 SOAP 服务器外,本身没有任何意义。与 REST 的不同的是,无法通过 URI 驱动 SOAP 方法调用。例如在我们的例子中,当我们通过
getUserList SOAP 消息获得所有的用户列表后,仍然无法通过既有的信息得到某个具体的用户信息。唯一的方法只有通过 WSDL 的指示,通过调用 getUserByName 获得,getUserList 与 getUserByName 是彼此孤立的。
而对于 REST,情况是完全不同的:通过 http://localhost:8182/v1/users
URI 获得用户列表,然后再通过用户列表中所提供的 LINK 属性,例如<link>http://localhost:8182/v1/users/tester</link>
获得 tester 用户的用户信息。这样的工作方式,非常类似于你在浏览器的某个页面上点击某个 hyperlink,浏览器帮你自动定向到你想访问的页面,并不依赖任何第三方的信息。
总结
典型的基于 SOAP 的 Web 服务以操作为中心,每个操作接受 XML 文档作为输入,提供 XML 文档作为输出。在本质上讲,它们是 RPC 风格的。而在遵循 REST 原则的 ROA 应用中,服务是以资源为中心的,对每个资源的操作都是标准化的 HTTP 方法。
本文主要集中在以上的几个方面,对 SOAP 与 REST 进行了对比,可以看到,基于 REST 构建的系统其系统的扩展能力要强于 SOAP,这可以体现在它的统一接口抽象、代理服务器支持、缓存服务器支持等诸多方面。并且,伴随着 Web Site as Web Services 演进的趋势,基于 REST 设计和实现的简单性和强扩展性,有理由相信,REST 将会成为 Web 服务的一个重要架构实践领域。
关于Web Service - RESTful 和 SOAP 笔记和soap restful webservice 区别的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services、java – SOAP webservice和RESTFUL webservice之间的区别、restful webservice SOAP webservice、RESTful Webservice 和 SOAP Webserivce 对比及区别的相关知识,请在本站寻找。
本文标签: