国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語(yǔ)言|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Spring學(xué)習(xí)筆記之RestTemplate使用小結(jié)

Spring學(xué)習(xí)筆記之RestTemplate使用小結(jié)

2021-05-25 12:29一灰灰 Java教程

這篇文章主要給大家介紹了關(guān)于Spring學(xué)習(xí)筆記之RestTemplate使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

作為一個(gè)java后端,需要通過(guò)http請(qǐng)求其他的網(wǎng)絡(luò)資源可以說(shuō)是一個(gè)比較常見(jiàn)的case了;一般怎么做呢?

可能大部分的小伙伴直接撈起apache的httpclient開(kāi)始做,或者用其他的一些知名的開(kāi)源庫(kù)如okhttp, 當(dāng)然原生的httpurlconnection也是沒(méi)問(wèn)題的

本篇博文則主要關(guān)注點(diǎn)放在sprig的生態(tài)下,利用resttemplate來(lái)發(fā)起http請(qǐng)求的使用姿勢(shì)

i. resttempalate 基本使用

0. 目標(biāo)

在介紹如何使用resttemplate之前,我們先拋出一些小目標(biāo),至少需要知道通過(guò)resttemplate可以做些什么,以及我們要用它來(lái)干些什么

簡(jiǎn)單的給出了一下常見(jiàn)的問(wèn)題如下

  • 普通的get請(qǐng)求獲取返回?cái)?shù)據(jù),怎么玩?
  • post提交表達(dá)的請(qǐng)求,如何處理
  • post請(qǐng)求中requestbody的請(qǐng)求方式與普通的請(qǐng)求方式區(qū)別
  • https/http兩種訪(fǎng)問(wèn)如何分別處理
  • 如何在請(qǐng)求中帶上指定的header
  • 有跨域的問(wèn)題么?如果有怎么解決
  • 有登錄驗(yàn)證的請(qǐng)求,該怎么辦,怎樣攜帶身份信息
  • 上傳文件可以支持么
  • 對(duì)于需要代理才能訪(fǎng)問(wèn)的http資源,加代理的姿勢(shì)是怎樣的

上面的問(wèn)題比較多,目測(cè)不是一篇博文可以弄完的,因此對(duì)這個(gè)拆解一下,本篇主要關(guān)注在resttemplate的簡(jiǎn)單get/post請(qǐng)求的使用方式上

1. 基本接口

撈出源碼,看一下其給出的一些常用接口,基本上可以分為下面幾種

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// get 請(qǐng)求
public <t> t getforobject();
public <t> responseentity<t> getforentity();
 
// head 請(qǐng)求
public httpheaders headforheaders();
 
// post 請(qǐng)求
public uri postforlocation();
public <t> t postforobject();
public <t> responseentity<t> postforentity();
 
// put 請(qǐng)求
public void put();
 
// pathch
public <t> t patchforobject
 
// delete
public void delete()
 
// options
public set<httpmethod> optionsforallow
 
// exchange
public <t> responseentity<t> exchange()

上面提供的幾個(gè)接口,基本上就是http提供的幾種訪(fǎng)問(wèn)方式的對(duì)應(yīng),其中exchange卻又不一樣,后面細(xì)說(shuō)

2. get請(qǐng)求

從上面的接口命名上,可以看出可以使用的有兩種方式 getforobject 和 getforentity,那么這兩種有什么區(qū)別?

  • 從接口的簽名上,可以看出一個(gè)是直接返回預(yù)期的對(duì)象,一個(gè)則是將對(duì)象包裝到 responseentity 封裝類(lèi)中
  • 如果只關(guān)心返回結(jié)果,那么直接用 getforobject 即可
  • 如果除了返回的實(shí)體內(nèi)容之外,還需要獲取返回的header等信息,則可以使用 getforentit

a. 創(chuàng)建get接口

為了驗(yàn)證resttemplate的使用姿勢(shì),當(dāng)然得先提供一個(gè)后端的rest服務(wù),這了直接用了我個(gè)人的一個(gè)古詩(shī)詞的后端接口,來(lái)作為簡(jiǎn)單的get測(cè)試使用

請(qǐng)求連接: https://story.hhui.top/detail?id=666106231640

返回結(jié)果:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
 "status": {
 "code": 200,
 "msg": "success"
 },
 "result": {
 "id": 666106231640,
 "title": "西塞山二首(今謂之道士磯,即興國(guó)軍大冶縣",
 "author": "王周",
 "content": "西塞名山立翠屏,濃嵐橫入半江青。\n千尋鐵鎖無(wú)由問(wèn),石壁空存道者形。\n匹婦頑然莫問(wèn)因,匹夫何去望千春。\n翻思岵屺傳詩(shī)什,舉世曾無(wú)化石人。",
 "explain": "",
 "theme": "無(wú)",
 "dynasty": "唐詩(shī)"
 }
}

b. getforobject方式

首先看下完整的接口簽名

?
1
2
3
4
5
6
7
8
@nullable
public <t> t getforobject(string url, class<t> responsetype, object... urivariables) throws restclientexception ;
 
@nullable
public <t> t getforobject(string url, class<t> responsetype, map<string, ?> urivariables) throws restclientexception ;
 
@nullable
public <t> t getforobject(uri url, class<t> responsetype) throws restclientexception;

有三個(gè)重載的方法,從接口上也比較容易看出如何使用,其中有點(diǎn)疑惑的則是第一鐘,參數(shù)應(yīng)該怎么傳了,下面給出上面幾種的使用姿勢(shì)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class resttestmplatetest {
 private resttemplate resttemplate;
 
 @before
 public void init() {
 resttemplate = new resttemplate();
 }
 
 @lombok.data
 static class innerres {
 private status status;
 private data result;
 }
 
 @lombok.data
 static class status {
 int code;
 string msg;
 }
 
 @lombok.data
 static class data {
 long id;
 string theme;
 string title;
 string dynasty;
 string explain;
 string content;
 string author;
 }
 
 @test
 public void testget() {
 // 使用方法一,不帶參數(shù)
 string url = "https://story.hhui.top/detail?id=666106231640";
 innerres res = resttemplate.getforobject(url, innerres.class);
 system.out.println(res);
 
 
 // 使用方法一,傳參替換
 url = "https://story.hhui.top/detail?id={?}";
 res = resttemplate.getforobject(url, innerres.class, "666106231640");
 system.out.println(res);
 
 // 使用方法二,map傳參
 url = "https://story.hhui.top/detail?id={id}";
 map<string, object> params = new hashmap<>();
 params.put("id", 666106231640l);
 res = resttemplate.getforobject(url, innerres.class, params);
 system.out.println(res);
 
 // 使用方法三,uri訪(fǎng)問(wèn)
 uri uri = uri.create("https://story.hhui.top/detail?id=666106231640");
 res = resttemplate.getforobject(uri, innerres.class);
 system.out.println(res);
 }
}

看上面的testcase,后面兩個(gè)方法的使用沒(méi)什么好說(shuō)的,主要看一下org.springframework.web.client.resttemplate#getforobject(java.lang.string, java.lang.class<t>, java.lang.object...) 的使用姿勢(shì)

  • 根據(jù)實(shí)際傳參替換url模板中的內(nèi)容
  • 使用方法一時(shí),模板中使用 {?} 來(lái)代表坑位,根據(jù)實(shí)際的傳參順序來(lái)填充
  • 使用方法二時(shí),模板中使用 {xx}, 而這個(gè)xx,對(duì)應(yīng)的就是map中的key

上面執(zhí)行后的截圖如下

Spring學(xué)習(xí)筆記之RestTemplate使用小結(jié)

c. getforentity方式

既然getforobject有三種使用方法,那么getforentity理論上也應(yīng)該有對(duì)應(yīng)的三種方式

?
1
2
3
public <t> responseentity<t> getforentity(string url, class<t> responsetype, object... urivariables) throws restclientexception ;
public <t> responseentity<t> getforentity(string url, class<t> responsetype, map<string, ?> urivariables) throws restclientexception;
public <t> responseentity<t> getforentity(uri url, class<t> responsetype) throws restclientexception;

因?yàn)槭褂米藙?shì)和上面一致,因此只拿一個(gè)進(jìn)行測(cè)試

?
1
2
3
4
5
6
@test
public void testgetforentity() {
 string url = "https://story.hhui.top/detail?id=666106231640";
 responseentity<innerres> res = resttemplate.getforentity(url, innerres.class);
 system.out.println(res);
}

對(duì)這個(gè),我們主要關(guān)注的就是responseentity封裝中,多了哪些東西,截圖如下

從上面可以看出,多了兩個(gè)東西

  • 一個(gè)返回的http狀態(tài)碼,如200表示請(qǐng)求成功,500服務(wù)器錯(cuò)誤,404not found等
  • 一個(gè) responseheader

3. post請(qǐng)求

從上面的接口說(shuō)明上看,post請(qǐng)求除了有forobject 和 forentity之外,還多了個(gè)forlocation;其次post與get一個(gè)明顯的區(qū)別就是傳參的姿勢(shì)問(wèn)題,get的參數(shù)一般會(huì)待在url上;post的則更常見(jiàn)的是通過(guò)表單的方式提交

因此接下來(lái)關(guān)注的重點(diǎn)在于forlocation是什么,以及如何傳參

a. post接口mock

首先創(chuàng)建一個(gè)簡(jiǎn)單的提供post請(qǐng)求的rest服務(wù),基于spring-boot簡(jiǎn)單搭建一個(gè),如下

?
1
2
3
4
5
6
7
8
9
10
@responsebody
@requestmapping(path = "post", method = {requestmethod.get, requestmethod.options, requestmethod.post})
public string post(httpservletrequest request,
 @requestparam(value = "email", required = false) string email,
 @requestparam(value = "nick", required = false) string nick) {
 map<string, object> map = new hashmap<>();
 map.put("code", "200");
 map.put("result", "add " + email + " # " + nick + " success!");
 return json.tojsonstring(map);
}

b. postforobject方法

首先看一下接口簽名

?
1
2
3
4
5
public <t> t postforobject(string url, @nullable object request, class<t> responsetype, object... urivariables) throws restclientexception ;
 
public <t> t postforobject(string url, @nullable object request, class<t> responsetype, map<string, ?> urivariables) throws restclientexception;
 
public <t> t postforobject(uri url, @nullable object request, class<t> responsetype) throws restclientexception ;

上面的三個(gè)方法,看起來(lái)和前面并沒(méi)有太大的區(qū)別,只是多了一個(gè)request參數(shù),那么具體的使用如何呢?

下面分別給出使用用例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@test
public void testpost() {
 string url = "http://localhost:8080/post";
 string email = "test@hhui.top";
 string nick = "一灰灰blog";
 
 multivaluemap<string, string> request = new linkedmultivaluemap<>();
 request.add("email", email);
 request.add("nick", nick);
 
 // 使用方法三
 uri uri = uri.create(url);
 string ans = resttemplate.postforobject(uri, request, string.class);
 system.out.println(ans);
 
 // 使用方法一
 ans = resttemplate.postforobject(url, request, string.class);
 system.out.println(ans);
 
 // 使用方法一,但是結(jié)合表單參數(shù)和uri參數(shù)的方式,其中uri參數(shù)的填充和get請(qǐng)求一致
 request.clear();
 request.add("email", email);
 ans = resttemplate.postforobject(url + "?nick={?}", request, string.class, nick);
 system.out.println(ans);
 
 
 // 使用方法二
 map<string, string> params = new hashmap<>();
 params.put("nick", nick);
 ans = resttemplate.postforobject(url + "?nick={nick}", request, string.class, params);
 system.out.println(ans);
}

復(fù)制代碼上面分別給出了三種方法的調(diào)用方式,其中post傳參區(qū)分為兩種,一個(gè)是uri參數(shù)即拼接在url中的,還有一個(gè)就是表單參數(shù)

  • uri參數(shù),使用姿勢(shì)和get請(qǐng)求中一樣,填充uri中模板坑位
  • 表單參數(shù),由multivaluemap封裝,同樣是kv結(jié)構(gòu)

c. postforentity

和前面的使用姿勢(shì)一樣,無(wú)非是多了一層包裝而已,略過(guò)不講

d. postforlocation

這個(gè)與前面有點(diǎn)區(qū)別,從接口定義上來(lái)說(shuō),主要是

post 數(shù)據(jù)到一個(gè)url,返回新創(chuàng)建資源的url

同樣提供了三個(gè)接口,分別如下,需要注意的是返回結(jié)果,為uri對(duì)象,即網(wǎng)絡(luò)資源

?
1
2
3
4
5
6
7
public uri postforlocation(string url, @nullable object request, object... urivariables)
 throws restclientexception ;
 
public uri postforlocation(string url, @nullable object request, map<string, ?> urivariables)
 throws restclientexception ;
 
public uri postforlocation(uri url, @nullable object request) throws restclientexception ;

那么什么樣的接口適合用這種訪(fǎng)問(wèn)姿勢(shì)呢?

想一下我們一般登錄or注冊(cè)都是post請(qǐng)求,而這些操作完成之后呢?大部分都是跳轉(zhuǎn)到別的頁(yè)面去了,這種場(chǎng)景下,就可以使用 postforlocation 了,提交數(shù)據(jù),并獲取返回的uri,一個(gè)測(cè)試如下

首先mock一個(gè)后端接口

?
1
2
3
4
5
6
7
8
9
10
11
@responsebody
@requestmapping(path = "success")
public string loginsuccess(string email, string nick) {
 return "welcome " + nick;
}
 
@requestmapping(path = "post", method = {requestmethod.get, requestmethod.options, requestmethod.post})
public string post(httpservletrequest request, @requestparam(value = "email", required = false) string email,
  @requestparam(value = "nick", required = false) string nick) {
 return "redirect:/success?email=" + email + "&nick=" + nick + "&status=success";
}

訪(fǎng)問(wèn)的測(cè)試用例,基本上和前面的一樣,沒(méi)有什么特別值得一說(shuō)的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@test
public void testpostlocation() {
 string url = "http://localhost:8080/post";
 string email = "test@hhui.top";
 string nick = "一灰灰blog";
 
 multivaluemap<string, string> request = new linkedmultivaluemap<>();
 request.add("email", email);
 request.add("nick", nick);
 
 // 使用方法三
 uri uri = resttemplate.postforlocation(url, request);
 system.out.println(uri);
}

執(zhí)行結(jié)果如下

Spring學(xué)習(xí)筆記之RestTemplate使用小結(jié)

獲取到的就是302跳轉(zhuǎn)后端url,細(xì)心的朋友可能看到上面中文亂碼的問(wèn)題,如何解決呢?

一個(gè)簡(jiǎn)單的解決方案就是url編碼一下

?
1
2
3
4
5
6
@requestmapping(path = "post", method = {requestmethod.get, requestmethod.options, requestmethod.post},
   produces = "charset/utf8")
public string post(httpservletrequest request, @requestparam(value = "email", required = false) string email,
  @requestparam(value = "nick", required = false) string nick) throws unsupportedencodingexception {
 return "redirect:/success?email=" + email + "&nick=" + urlencoder.encode(nick, "utf-8") + "&status=success";
}

ii. 小結(jié)

上面目前只給出了get/post兩種請(qǐng)求方式的基本使用方式,并沒(méi)有涉及到更高級(jí)的如添加請(qǐng)求頭,添加證書(shū),設(shè)置代理等,高級(jí)的使用篇等待下一篇出爐,下面小結(jié)一下上面的使用姿勢(shì)

1. get請(qǐng)求

get請(qǐng)求中,參數(shù)一般都是帶在url上,對(duì)于參數(shù)的填充,有兩種方式,思路一致都是根據(jù)實(shí)際的參數(shù)來(lái)填充url中的占位符的內(nèi)容;根據(jù)返回結(jié)果,也有兩種方式,一個(gè)是只關(guān)心返回對(duì)象,另一個(gè)則包含了返回headers信心
參數(shù)填充

1、形如  http://story.hhui.top?id={0} 的 url

  • 調(diào)用 getforobject(string url, class<t> responsetype, object... urivariables)
  • 模板中的0,表示 urivariables 數(shù)組中的第0個(gè), i,則表示第i個(gè)
  • 如果沒(méi)有url參數(shù),也推薦用這個(gè)方法,不傳urivariables即可

2、形如  http://story.hhui.top?id={id} 的 url

  • 調(diào)用 getforobject(string url, class<t> responsetype, map<string, ?> urivariables)
  • map參數(shù)中的key,就是url參數(shù)中 {} 中的內(nèi)容

其實(shí)還有一種傳參方式,就是path參數(shù),填充方式和上面一樣,并沒(méi)有什么特殊的玩法,上面沒(méi)有特別列出

返回結(jié)果

  • 直接獲取返回的數(shù)據(jù)  getforobject
  • 獲取待responseheader的數(shù)據(jù) getforentity

2. post請(qǐng)求

  • post請(qǐng)求的返回也有兩種,和上面一樣
  • post請(qǐng)求,參數(shù)可以區(qū)分為表單提交和url參數(shù),其中url參數(shù)和前面的邏輯一致
  • post表單參數(shù),請(qǐng)包裝在 multivaluemap 中,作為第二個(gè)參數(shù) request 來(lái)提交
  • post的方法,還有一個(gè) postforlocation,返回的是一個(gè)uri對(duì)象,即適用于返回網(wǎng)絡(luò)資源的請(qǐng)求方式

3. 其他

最前面提了多點(diǎn)關(guān)于網(wǎng)絡(luò)請(qǐng)求的常見(jiàn)case,但是上面的介紹,明顯只處于基礎(chǔ)篇,我們還需要關(guān)注的有

  • 如何設(shè)置請(qǐng)求頭?
  • 有身份驗(yàn)證的請(qǐng)求,如何攜帶身份信息?
  • 代理的設(shè)置
  • 文件上傳可以怎么做?
  • post提交json串(即requestbody) 又可以怎么處理

上面可能還停留在應(yīng)用篇,對(duì)于源碼和實(shí)現(xiàn)有興趣的話(huà),問(wèn)題也就來(lái)了

  • resttemplaet的實(shí)現(xiàn)原理是怎樣的
  • 前面url參數(shù)的填充邏輯實(shí)現(xiàn)是否優(yōu)雅
  • 返回的對(duì)象如何解析
  • ....

小小的一個(gè)工具類(lèi),其實(shí)東西還挺多的,接下來(lái)的小目標(biāo),就是針對(duì)上面提出的點(diǎn),逐一進(jìn)行研究

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。

原文鏈接:https://juejin.im/post/5b717eab6fb9a0096e21cc24

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩激情一区二区三区 | 日韩欧美高清 | 国产免费成人 | 国产欧美日韩免费 | 午夜影院 | 亚洲一区二区在线视频 | 亚洲精品视频在线观看网站 | 亚洲日韩欧美一区二区在线 | 视频一区在线播放 | 精品国产乱码久久久久久久软件 | 福利视频在线 | 亚洲天堂成人在线 | 久久国内 | 新久久久 | 国产一区二区三区在线看 | 国产精品毛片久久久久久久av | a∨色狠狠一区二区三区 | 午夜国产在线 | 久久精品中文 | 亚洲色视频 | 一区二区三区视频 | 久久免费99精品久久久久久 | 一区二区三区欧美在线 | 欧美freesex交免费视频 | 午夜影院啊啊啊 | 久久er99热精品一区二区 | 成人在线一区二区 | 亚洲激情在线播放 | 午夜tv| 国产玖玖 | 久草视频在线播放 | 另类视频在线 | 欧美在线不卡 | 日本久久精品视频 | 亚州中文字幕 | 一区二区三区四区在线视频 | 黄色一级网站视频 | 久久久久99精品国产片 | 91av电影在线观看 | 男女激情网址 | 国产精品久久久久久久久久免费看 |