Spring RestTemplate详解

来源:互联网 发布:罗赛塔石碑软件 编辑:程序博客网 时间:2024/06/01 07:36

Spring RestTemplate请参见 [ 官方文档]的Accessing REST endpoints部分,借助一下博文更容易理解。

什么是Rest

REST(RepresentationalState Transfer)是Roy Fielding提出的一个描述互联系统架构风格的名词。REST定义了一组体系架构原则,可以根据这些原则设计以系统资源为中心的Web服务,包括使用不同语言编写的客户端如何通过HTTP处理和传输资源状态。

[ 举个例子 ]
简单的理解,Restful是一种url风格,或者说是一种规范,在以前的网址中,假定一个业务,取得数据网址为http://test/get,添加信息的网址为http://test/post,类似这样。 但是在restful风格中,取得数据和添加数据的网址均应为http://test,方法为get或者post;所以,在restful风格中,一个网址就是一个资源,其形式类似于http://xxx.com/xx/{id}/{id} ,例如某购物网站,产品有很多种类,每种产品下有很多子类型,那么http://shop.com/laptop/lenovo/1103 代表了联想1103型号电脑,而http://shop.com/laptop/hp/1024 代表了2014型号电脑。

在spring mvc中,有@requestparm, @requestbody和@pathvariable 三种注解来获得浏览器端的参数,其中前两者都是由浏览器post提交的参数,而@pathvariable 则是从网址中取得参数;假设代码如下:

@Requestmapping(value="/{category}/{brand}/{id},method=RequestMethod.POST)public void getbyid(@PathVariable("category") String category                    @PathVariable("brand") String brand                    @PathVariable("id") String id){                    //具体代码略}

在上述代码中,访问http://shop.com/laptop/hp/1024网址时,则,category为“laptop”,brand为”hp”,id为”1024”;所以说,在restful风格中,一个网址即表示了一个资源。其中还有关于restcontroller和controller的详细区别。

RestTemplate

RestTemplate是Spring提供的用于访问Rest服务的客户端,Resttemplate提供了多种便捷访问远程Http服务的方法,能够大大的提高客户端的编写效率。简单说就是:简化了发起HTTP请求以及处理相应的过程,并且支持REST。
RestTemplate可以通过使用ClientHttpRequestFactory来指定不同的HTTP请求方式:
- SimpleClientHttpRequestFactory:RestTemplate默认是使用它,原理是调用jdk的HttpConnection,默认超时未-1;
- HttpComponentsClientHttpRequestFactory:原理使用HttpClient链接吃的方式。
RestTemplate的XML配置、用java代码使用的详例请查看链接 [ 详例 ]

RestTemplate对外开放的接口

(1)RestTemplate在HTTP client的基础上提供更高级的(封装得更好的)API,API method对应了HTTP的6种主要method,这样可以调用许多REST服务,并让REST实践更佳。
RestTemplate的取名方式遵循这样的命名习俗:第一部分indicates使用的HTTP method,第二部分indicates返回的结果。
Overview of RestTemplate methods

HTTP Method RestTemplate Method DELETE delete GET getForObject getForEntity HEAD headForHeaders(String url, String…​ uriVariables) OPTIONS optionsForAllow(String url, String…​ uriVariables) POST postForLocation(String url, Object request, String…​ uriVariables) postForObject(String url, Object request, Class responseType, String…​ uriVariables) PUT put(String url,Object request,String…ruiVariables) PATCH and others exchange execute

这里写图片描述
(2)以上Overview的每个小类又分三种,这三种有什么区别?
- 第一种和第二种的首个参数都是用String表示一个URL,最后一个参数是Object或者Map
- 第三种的首个参数是使用URI,且只有两个参数
但是第一二种方法用String有一个小缺陷:String形式的URI会被编码两次(URL encode自行百度),这就要求服务器在获取URI中的参数时主动进行解码,但是如果服务的提供者不这么做呢?
那么Rest Template就提供了:对于每一种main HTTP methods,RestTemplate提供让第一个参数使用String URI或者java.net.URI的方法(即:第三种);String URI接收String variable-length argment或者Map’<’String,String>的模版参数(Template arguments)。
直接使用String举个例子:

restTemplate.getForObject("http://example.com/hotel list",String.class);

将会perform a GET on “http://example.com/hotel%20list”,这意味着输入的URL String已经encoded,并且还会被第二次encoded成“http://example.com/hotel%2520list”,如果这不是想要的结果,用java.net.URI method,这个method假定URL已经encoded并且是通用如果你想要重复使用URI多次。
使用variable-length arguments例子:

String result = restTemplate.getForObject("http://example/hotels/{hotels}/bookings/{booking}",String.class,"42","21");

使用Map<’String,String> arguments例子

Map<String,String> vars = Collections.singletonMap("hotel","42");String result = restTemplate.getForObject("http://example/hotels/{hotels}/bookings/{booking}",String.class,vars);

(3)Exchange接口
(a)与其他接口的不同:允许调用者指定HTTP请求的方法(GET、POST、PUT等);
(b)可以在请求中增加body和headers信息,其内容通过HttpEntity

ParameterizedTypeReference pt = new ParameterizedTypeReference<ArrayList<String>>() {}; 

(4)excute接口
所有的方法:get、post、delete、put、options、head、exchange方法最终调用的都是excite方法。
举个例子:

@Overridepublic <T> T getObject(String url,Class<T> responseType,Object.. urlVaraiables) throws RestClientException{    RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);    HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor<T>(responseType, getMessageConverters(), logger);  return execute(url, HttpMethod.GET, requestCallback, responseExtractor, urlVariables);  }

其中Excute方法只是将String格式的URI转成了java.net.URI,之后调用了doExcute方法,要深究Excute和doExcute方法以及RequestCallback(用于操作请求headers和body,在请求发出前执行)和ResponseExtractor(解析HTTP响应的数据,并且不需要担心异常和资源关闭)的理论原理,参考 [ 博客 ]。

原创粉丝点击