RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率 。我之前的HTTP开发是用Apache的HttpClient开发,代码复杂,还得操心资源回收等 。代码很复杂,冗余代码多,稍微截个图,这是我封装好的一个post请求工具:
![RestTemplate详解 Springboot — 用更优雅的方式发HTTP请求](http://img.jiangsulong.com/230914/1J6043F8-0.jpg)
文章插图
本教程将带领大家实现Spring生态内RestTemplate的Get请求和Post请求还有exchange指定请求类型的实践和RestTemplate核心方法源码的分析,看完你就会用优雅的方式来发HTTP请求 。
1. 简述RestTemplate
是Spring用于同步client端的核心类,简化了与http服务的通信,并满足RestFul原则,程序代码可以给它提供URL,并提取结果 。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具 。当然你也可以 通过setRequestFactory属性切换到不同的HTTP源,比如Apache HttpComponents?.NETty和OkHttp 。RestTemplate能大幅简化了提交表单数据的难度,并且附带了自动转换JSON数据的功能,但只有理解了HttpEntity的组成结构(header与body),且理解了与uriVariables之间的差异,才能真正掌握其用法 。这一点在Post请求更加突出,下面会介绍到 。
该类的入口主要是根据HTTP的六个方法制定:
RestTemplate methods
DELETE
delete
GET
getForObject
getForEntity
HEAD
headForHeaders
OPTIONS
optionsForAllow
POST
postForLocation
postForObject
PUT
put
any
exchange
execute
此外,exchange和excute可以通用上述方法 。
在内部,RestTemplate默认使用HttpMessageConverter实例将HTTP消息转换成POJO或者从POJO转换成HTTP消息 。默认情况下会注册主mime类型的转换器,但也可以通过setMessageConverters注册其他的转换器 。(其实这点在使用的时候是察觉不到的,很多方法有一个responseType 参数,它让你传入一个响应体所映射成的对象,然后底层用HttpMessageConverter将其做映射)
HttpMessageConverterExtractor<T> responseExtractor =new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
HttpMessageConverter.JAVA源码:public interface HttpMessageConverter<T> {//指示此转换器是否可以读取给定的类 。boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);//指示此转换器是否可以写给定的类 。boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);//返回List<MediaType> List<MediaType> getSupportedMediaTypes();//读取一个inputMessage T read(Class<? extends T> clazz, HttpInputMessage inputMessage)throws IOException, HttpMessageNotReadableException;//往output message写一个Object void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)throws IOException, HttpMessageNotWritableException;}
在内部,RestTemplate默认使用SimpleClientHttpRequestFactory和DefaultResponseErrorHandler来分别处理HTTP的创建和错误,但也可以通过setRequestFactory和setErrorHandler来覆盖 。
2. get请求实践2.1. getForObject()方法
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables){}public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)public <T> T getForObject(URI url, Class<T> responseType)
getForObject()其实比getForEntity()多包含了将HTTP转成POJO的功能,但是getForObject没有处理response的能力 。因为它拿到手的就是成型的pojo 。省略了很多response的信息 。2.1.1 POJO:
public class Notice {private int status;private Object msg;private List<DataBean> data;}publicclass DataBean {private int noticeId;private String noticeTitle;private Object noticeImg;private long noticeCreateTime;private long noticeUpdateTime;private String noticeContent;}
示例:2.1.2 不带参的get请求 /*** 不带参的get请求*/ @Test public void restTemplateGetTest(){RestTemplate restTemplate = new RestTemplate();Notice notice = restTemplate.getForObject("http://xxx.top/notice/list/1/5", Notice.class);System.out.println(notice); }
控制台打印:INFO 19076 --- [mAIn] c.w.s.c.w.c.HelloControllerTest: Started HelloControllerTest in 5.532 seconds (JVM running for 7.233)Notice{status=200, msg=null, data=https://www.isolves.com/it/cxkf/jiagou/2023-09-14/[DataBean{noticeId=21, noticeTitle='aaa', noticeImg=null, noticeCreateTime=1525292723000, noticeUpdateTime=1525292723000, noticeContent='aaa
'}, DataBean{noticeId=20, noticeTitle='ahaha', noticeImg=null, noticeCreateTime=1525291492000, noticeUpdateTime=1525291492000, noticeContent='
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 详解Spring支持的各种数据类型的注入,你都用过哪些?
- 谷雨养生知识详解 谷雨养生知识详解图
- 保护Linux文件和目录的秘密武器:chattr命令详解
- 钓鱼必杀技:盒饭钓法详解,野钓大鲫鱼第一利器
- SpringBoot实现多数据源配置详解
- 网络层协议详解:理解TCP/IP、HTTP、FTP等协议的功能与工作原理
- 详解秋季钓鲤鱼,适合钓深水还是钓浅水?很多钓友选错了!
- 陈百强65岁冥诞众星现身!何超琼因缺席惹负评,知情人详解原因
- 天官赐福卦象怎么理解 天官赐福卦白话详解
- SpringBoot整合Druid进行SQL监控、SQL慢查询