REST(RepresentationalState Transfer)是Roy Fielding 提出的一个描述互联系统架构风格的名词。REST定义了一组体系架构原则,您能够根据这些原则设计以系统资源为中心的Web 服务,包括使用不一样语言编写的客户端如何经过 HTTP处理和传输资源状态。html
为何称为 REST?Web本质上由各类各样的资源组成,资源由URI 惟一标识。浏览器(或者任何其它相似于浏览器的应用程序)将展现出该资源的一种表现方式,或者一种表现状态。若是用户在该页面中定向到指向其它资源的连接,则将访问该资源,并表现出它的状态。这意味着客户端应用程序随着每一个资源表现状态的不一样而发生状态转移,也即所谓REST。java
第一个层次(Level0)的Web 服务只是使用 HTTP 做为传输方式,实际上只是远程方法调用(RPC)的一种具体形 式。SOAP和 XML-RPC都属于此类。浏览器
第二个层次(Level1)的Web 服务引入了资源的概念。每一个资源有对应的标识符和表达。缓存
第三个层次(Level2)的Web 服务使用不一样的 HTTP 方法来进行不一样的操做,而且使用HTTP 状态码来表示不一样的结果。如 HTTPGET 方法来获取资源,HTTPDELETE 方法来删除资源。服务器
第四个层次(Level3)的Web 服务使用 HATEOAS。在资源的表达中包含了连接信息。客户端能够根据连接来发现能够执行的动做。restful
其中第三个层次创建了建立、读取、更新和删除(create,read, update, and delete,CRUD)操做与 HTTP方法之间的一对一映射。根据此映射:架构
(1)若要在服务器上建立资源,应该使用POST 方法。app
(2)若要检索某个资源,应该使用GET 方法。ide
(3)若要更改资源状态或对其进行更新,应该使用PUT 方法。
(4)若要删除某个资源,应该使用DELETE 方法。
(1)GET:经过请求URI获得资源
(2)POST:用于添加新的内容
(3)PUT:用于修改某个内容,若不存在则添加
(4)DELETE:删除某个内容
(5)OPTIONS :询问能够执行哪些方法
(6)HEAD :相似于GET, 可是不返回body信息,用于检查对象是否存在,以及获得对象的元数据
(7)CONNECT :用于代理进行传输,如使用SSL
(8)TRACE:用于远程诊断服务器
(1)成功Successful2xx:此类状态码标识客户端的请求被成功接收、理解并接受。常见如200(OK)、204(NoContent)。
(2)重定向Redirection3xx:这个类别的状态码标识用户代理要作出进一步的动做来完成请求。常见如301(MovedPermanently)、302(MovedTemprarily)。
(3)客户端错误Client Error 4xx:4xx类别的状态码是当客户端象是出错的时使用的。常见如400(BadRequest)、401(Unauthorized)、403(Forbidden)、404(NotFound)。
(4)服务器错误Server Error 5xx:响应状态码以5开头表示服务器知道本身出错或者没有能力执行请求。常见如500(InternalServer Error)、502(BadGateway)、504(GatewayTimeout)。
附HTTP1.1的标准简介:http://blog.chinaunix.net/uid-9188830-id-2007021.html
Spring'scentral class for synchronous client-side HTTP access.It simplifies communication with HTTPservers, and enforces RESTful principles. Ithandles HTTP connections, leaving application code to provide URLs(with possible template variables) andextract results.
简单说就是:简化了发起HTTP请求以及处理响应的过程,而且支持REST。为何说简化了呢?
来看两种实现方式
(1)使用java.net包下的URLConnection创建链接
String result= ""; BufferedReaderin = null; try { String urlNameString= url +"?" + param; URL realUrl= new URL(urlNameString); // 打开和URL之间的链接 URLConnectionconnection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept","*/*"); connection.setRequestProperty("connection","Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0(compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 创建实际的链接 connection.connect(); // 获取全部响应头字段 Map<String,List<String>> map = connection.getHeaderFields(); // 遍历全部的响应头字段 for(String key : map.keySet()) { System.out.println(key+ "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in =new BufferedReader(newInputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine())!= null) { result += line; } } catch (Exception e) { … } // 使用finally块来关闭输入流 finally{ // 关闭流 }
(2)使用RestTempalte
ResponseEntity<SsoUrlPrm>result = restTemplate.getForEntity(requestPathUrl,SsoUrlPrm.class);
(1)
DELETE | delete |
GET | getForObject |
getForEntity | |
HEAD | headForHeaders |
OPTIONS | optionsForAllow |
POST | postForLocation |
postForObject | |
PUT | put |
any | exchange |
execute |
这是由于,String类型的URI支持占位符。好比:
restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}",String.class,"42", "21");
那么最终访问的URI为:http://example.com/hotels/42/bookings/21
可是String有一个小缺陷:String形式的URI会被URL编码两次(URL encode请自行百度),这就要求服务器在获取URI中的参数时主动进行一次解码,但若是服务的提供者不这么作呢?
这时就须要使用不会使用任何编码的java.net.URI
PS:参数‘Class<T> responseType’定义了返回数据的类型。
>容许调用者指定HTTP请求的方法(GET,POST,PUT等)
>能够在请求中增长body以及头信息,其内容经过参数‘HttpEntity<?>requestEntity’描述
>exchange支持‘含参数的类型’(即泛型类)做为返回类型,该特性经过‘ParameterizedTypeReference<T>responseType’描述。好比:
List<String> a = new ArrayList<String>(); System.out.println(a.getClass()); System.out.println(a.getClass().getGenericSuperclass()); ParameterizedTypeReference pt = new ParameterizedTypeReference<ArrayList<String>>() {}; System.out.println(pt.getType());
获得的结果是:
class java.util.ArrayList java.util.AbstractList<E> java.util.ArrayList<java.lang.String>
@Override public <T> T getForObject(String url, Class<T> responseType, Object... urlVariables) throws RestClientException { RequestCallback requestCallback = acceptHeaderRequestCallback(responseType); HttpMessageConverterExtractor<T> responseExtractor = <span style="white-space:pre"> </span>new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger); return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables); }
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,ResponseExtractor<T> responseExtractor) throws RestClientException {…}
AcceptHeaderRequestCallback | 只处理请求头,用于getXXX()方法。 |
HttpEntityRequestCallback | 继承于AcceptHeaderRequestCallback能够处理请求头和body,用于putXXX()、postXXX()和exchange()方法。 |
HeadersExtractor | 用于提取请求头。 |
HttpMessageConverterExtractor | 用于提取响应body。 |
ResponseEntityResponseExtractor | 使用HttpMessageConverterExtractor提取body(委托模式),而后将body和响应头、状态封装成ResponseEntity对象。 |
转化器 |
可转化的类型 |
ByteArrayHttpMessageConverter | byte[] |
StringHttpMessageConverter | String |
ResourceHttpMessageConverter | Resource |
SourceHttpMessageConverter | javax.xml.transform.* |
AllEncompassingFormHttpMessageConverter | MultiValueMap |
Jaxb2RootElementHttpMessageConverter | XmlRootElement,XmlType(注解) |
... | |
MappingJackson2HttpMessageConverter | Json |
TOKEN |
Json的一个或一组字符 |
START_OBJECT | { |
END_OBJECT | } |
START_ARRAY | [ |
END_ARRAY | ] |
VALUE_TRUE | true |
VALUE_FALSE | false |
... |
调用栈: