【Spring-web】RestTemplate源码学习
前言
这种开发内容除了业务逻辑,剩下的基本都是套路代码,而Spring从3.0版本开始,为我们提供了封装好的访问HTTP的模板代码RestTemplate。
RestTemplate 类说明
/**
* <strong>Spring's central class for synchronous client-side HTTP access.</strong>
* It simplifies communication with HTTP servers, and enforces RESTful principles.
* It handles HTTP connections, leaving application code to provide URLs
* (with possible template variables) and extract results.
*
* <p><strong>Note:</strong> by default the RestTemplate relies on standard JDK
* facilities to establish HTTP connections. You can switch to use a different
* HTTP library such as Apache HttpComponents, Netty, and OkHttp through the
* {@link #setRequestFactory} property.
*
* <p>The main entry points of this template are the methods named after the six main HTTP methods:
* <table>
* <tr><th>HTTP method</th><th>RestTemplate methods</th></tr>
* <tr><td>DELETE</td><td>{@link #delete}</td></tr>
* <tr><td>GET</td><td>{@link #getForObject}</td></tr>
* <tr><td></td><td>{@link #getForEntity}</td></tr>
* <tr><td>HEAD</td><td>{@link #headForHeaders}</td></tr>
* <tr><td>OPTIONS</td><td>{@link #optionsForAllow}</td></tr>
* <tr><td>POST</td><td>{@link #postForLocation}</td></tr>
* <tr><td></td><td>{@link #postForObject}</td></tr>
* <tr><td>PUT</td><td>{@link #put}</td></tr>
* <tr><td>any</td><td>{@link #exchange}</td></tr>
* <tr><td></td><td>{@link #execute}</td></tr> </table>
*
* <p>In addition the {@code exchange} and {@code execute} methods are generalized versions of
* the above methods and can be used to support additional, less frequent combinations (e.g.
* HTTP PATCH, HTTP PUT with response body, etc.). Note however that the underlying HTTP
* library used must also support the desired combination.
*
* <p>For each HTTP method there are three variants: two accept a URI template string
* and URI variables (array or map) while a third accepts a {@link URI}.
* Note that for URI templates it is assumed encoding is necessary, e.g.
* {@code restTemplate.getForObject("http://example.com/hotel list")} becomes
* {@code "http://example.com/hotel%20list"}. This also means if the URI template
* or URI variables are already encoded, double encoding will occur, e.g.
* {@code http://example.com/hotel%20list} becomes
* {@code http://example.com/hotel%2520list}). To avoid that use a {@code URI} method
* variant to provide (or re-use) a previously encoded URI. To prepare such an URI
* with full control over encoding, consider using
* {@link org.springframework.web.util.UriComponentsBuilder}.
*
* <p>Internally the template uses {@link HttpMessageConverter} instances to
* convert HTTP messages to and from POJOs. Converters for the main mime types
* are registered by default but you can also register additional converters
* via {@link #setMessageConverters}.
*
* <p>This template uses a
* {@link org.springframework.http.client.SimpleClientHttpRequestFactory} and a
* {@link DefaultResponseErrorHandler} as default strategies for creating HTTP
* connections or handling HTTP errors, respectively. These defaults can be overridden
* through {@link #setRequestFactory} and {@link #setErrorHandler} respectively.
*
* @author Arjen Poutsma
* @author Brian Clozel
* @author Roy Clarkson
* @author Juergen Hoeller
* @since 3.0
* @see HttpMessageConverter
* @see RequestCallback
* @see ResponseExtractor
* @see ResponseErrorHandler
* @see AsyncRestTemplate
*/
Java Doc

补充说明:
重载的3个方法怎么选择呢?建议选择URL参数类型为String的那个两个方法。因为当这个参数是一个非URI格式的,需要进行转换,而URI的构造函数会抛出一个检查异常URISyntaxException,该异常必须捕获。另外两个重载方法则避免了捕获异常,所以上面表格中推荐的方法的第一个参数都是String类型。
简单例子
package com.practice; import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map; import junit.framework.TestCase;
import net.sf.json.JSONObject; import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate; public class RestTemplateTest extends TestCase { RestTemplate restTpl; @Before
public void setUp() {
restTpl = new RestTemplate();
} @Test
public void testGet() {
Map<String, Object> paramsMap = new HashMap<String, Object>();
paramsMap.put("cityCode", "xxxxxxxxxx");
paramsMap.put("key", "xxxxxxxxxxxxxxxxxxxxx"); String url = "http://xxx.xxx.xxx.xxx:8080/xxx/xxxx?xxxx&config=xxx&cityCode={cityCode}&key={key}";
String respStr = restTpl.getForObject(url, String.class, paramsMap);
System.out.println(respStr); JSONObject respJson = restTpl.getForObject(url, JSONObject.class, paramsMap);
System.out.println(respJson);
} @Test
public void testPost() throws Exception {
String posturl = "http://xxx.xxx.xxx.xxx:8080/xxxx/xxxx/xxxxx"; JSONObject metadata = new JSONObject();
metadata.put("dddddd", "xxxxx");
metadata.put("ssssss", "xxxxxx");
metadata.put("flag", true); JSONObject paramsJson = new JSONObject();
paramsJson.put("mmmmm", "mmm");
paramsJson.put("nnnnn", "nnn");
paramsJson.put("password", "xxxxxxxxxxx");
paramsJson.put("metadata", metadata); String params = "RequestJson=" + URLEncoder.encode(paramsJson.toString(), "utf-8"); MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); HttpEntity<Object> hpEntity = new HttpEntity<Object>(params, headers); ResponseEntity<String> respEntity = restTpl.postForEntity(posturl, hpEntity, String.class);
System.out.println(respEntity);
} }
然而,就是这么简单的几行代码还不断出错~~~~~~~


疑问解答
RestTemplate中是如何处理请求头信息的呢?
以GET方法为例,getForObject()方法中有这么一句【RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);】

这里为什么使用内部类呢?
复习下内部类的作用:
【Spring-web】RestTemplate源码学习的更多相关文章
- spring源码学习(三)--spring循环引用源码学习
在spring中,是支持单实例bean的循环引用(循环依赖)的,循环依赖,简单而言,就是A类中注入了B类,B类中注入了A类,首先贴出我的代码示例 @Component public class Add ...
- 捋一捋Spring Web的源码思路
Servlet前提 Java规定了Servlet Container为每一个web app创建一个Servlet Context:而Servlet Context中又包含了诸多Servlet -- 其 ...
- 【Spring-web】RestTemplate源码学习——梳理内部实现过程
2016-12-28 by 安静的下雪天 http://www.cnblogs.com/quiet-snowy-day/p/6228198.html 提示:使用手机浏览时请注意,图多费流量. 本篇 ...
- 【目录】Spring 源码学习
[目录]Spring 源码学习 jwfy 关注 2018.01.31 19:57* 字数 896 阅读 152评论 0喜欢 9 用来记录自己学习spring源码的一些心得和体会以及相关功能的实现原理, ...
- spring源码学习——spring整体架构和设计理念
Spring是在Rod Johnson的<Expert One-On-One J2EE Development and Design >的基础上衍生而来的.主要目的是通过使用基本的java ...
- Spring5.0源码学习系列之Spring AOP简述
前言介绍 附录:Spring源码学习专栏 在前面章节的学习中,我们对Spring框架的IOC实现源码有了一定的了解,接着本文继续学习Springframework一个核心的技术点AOP技术. 在学习S ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- SpringBoot源码学习1——SpringBoot自动装配源码解析+Spring如何处理配置类的
系列文章目录和关于我 一丶什么是SpringBoot自动装配 SpringBoot通过SPI的机制,在我们程序员引入一些starter之后,扫描外部引用 jar 包中的META-INF/spring. ...
- spring源码学习之路---深入AOP(终)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...
随机推荐
- TCP和UDP的区别
(1)TCP是面向连接的传输控制协议,而UDP提供了无连接的数据报服务:(2)TCP具有高可靠性,确保传输数据的正确性,不出现丢失或乱序:UDP在传输数据前不建立连接,不对数据报进行检查与修改,无须等 ...
- SDOI 2016 生成魔咒
题目大意:一个字符串,刚开始为空,依次在后面添加一个字符,问每次添加完字符后本质不同的字符串有多少种 后缀自动机裸题,添加字符时,更新的结点个数即为新增加的子串 #include<bits/st ...
- dev GridControl 根据鼠标坐标 选中行
if (e.Button == System.Windows.Forms.MouseButtons.Right) { DevExpress.XtraGrid.Views.Grid.ViewInfo.G ...
- Apache许可协议Open RIA Services
Jeff Handley's进行了多年的项目--基于一份开源许可发布WCF RIA Services.遵循Apache 2许可,捐赠给Outercurve基金会的ASP.NET Open Source ...
- ABP理论学习之日志记录
返回总目录 本篇目录 服务端 获取Logger 基类中的Logger 配置 客户端 服务端 ABP使用的是Castle Windsor的日志记录设备.它可以和不同的日志类库一起工作,比如Log4Net ...
- 可以这样去理解group by和聚合函数
写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不过来,为什么不能够select * from Table group by id,为什么一定不能是 ...
- CSharpGL(3)使用CSharpGL.vsix插件
CSharpGL(3)使用CSharpGL.vsix插件 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更 ...
- 神兵利器——Alfred
有人的地方就有江湖,有江湖就有纷争. 很多人说我的文字风格相对轻松和温和,那是因为我很早就认识到,我们没有教育脑残和喷子的义务.在网际多年,看过太多虚拟的刀锋和鲜血,很多人被彻头彻尾的粉碎,挫骨扬灰, ...
- JS实战 · 复选框全选操作
思路: 1.获取被选中checkbox,通过checked属性的状态完成: 2.获取被选中的checkbox的value值: 3.求所有value的和sum: 4.定义span区域存储和sum: ...
- SVN+码云 简单使用流程
1.登录码云网站...