關于Spring RestTemplate

?
一、概述


RestTemplate?是 Spring Framework 提供的一個同步 HTTP 客戶端工具,用于簡化與 RESTful API 的交互。它封裝了底層 HTTP 通信細節,提供了統一的 API 來發送各種 HTTP 請求(GET、POST、PUT、DELETE 等),并自動處理響應數據的序列化和反序列化。

二、依賴配置


如果使用 Maven 項目,需要在?pom.xml?中添加以下依賴:

xml

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

三、基本使用流程

RestTemplate restTemplate = new RestTemplate();

// 示例:發送 GET 請求獲取用戶信息

String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, 123);

四、HTTP 請求方法詳解


1. GET 請求
獲取資源的基本方法有兩種:

1.1?getForObject()?- 直接返回響應體

String url = "https://api.example.com/users/{id}";
User user = restTemplate.getForObject(url, User.class, 123);

參數說明:
url:請求 URL,可以包含占位符(如?{id})
responseType:響應數據類型(通常是實體類)
uriVariables:占位符參數值(可變參數或 Map)
1.2?getForEntity()?- 返回完整響應實體

ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, 123);
if (response.getStatusCode() == HttpStatus.OK) {User user = response.getBody();HttpHeaders headers = response.getHeaders();
}

2. POST 請求
用于創建資源,常用方法有三種:

2.1?postForObject()?- 直接返回響應體

User newUser = new User("Alice", 25);
String url = "https://api.example.com/users";
User createdUser = restTemplate.postForObject(url, newUser, User.class);

參數說明:
url:請求 URL
request:請求體對象(會自動序列化為 JSON/XML)
responseType:響應數據類型
2.2?postForEntity()?- 返回完整響應實體

ResponseEntity<User> response = restTemplate.postForEntity(url, newUser, User.class);

2.3?postForLocation()?- 返回新創建資源的 URL

URI location = restTemplate.postForLocation(url, newUser);

3. PUT 請求
用于更新資源(全量更新):

User updatedUser = new User(123, "Bob", 30);
String url = "https://api.example.com/users/{id}";
restTemplate.put(url, updatedUser, 123);

4. DELETE 請求
用于刪除資源:

String url = "https://api.example.com/users/{id}";
restTemplate.delete(url, 123);

5. PATCH 請求(部分更新)
使用通用的?exchange()?方法:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

// 創建包含部分更新數據的 Map

Map<String, Object> updates = new HashMap<>();
updates.put("age", 31);HttpEntity<Map<String, Object>> request = new HttpEntity<>(updates, headers);
String url = "https://api.example.com/users/{id}";ResponseEntity<User> response = restTemplate.exchange(url,?HttpMethod.PATCH,?request,?User.class,?123
);

五、處理復雜請求


1. 自定義請求頭
使用?HttpEntity?包裝請求體和請求頭:

HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer token123");
headers.setContentType(MediaType.APPLICATION_JSON);User requestBody = new User("Charlie", 35);
HttpEntity<User> request = new HttpEntity<>(requestBody, headers);String url = "https://api.example.com/secure/users";
ResponseEntity<User> response = restTemplate.exchange(url, HttpMethod.POST, request, User.class);

2. 處理查詢參數
使用?UriComponentsBuilder?構建帶查詢參數的 URL:

UriComponents uriComponents = UriComponentsBuilder.fromUriString("https://api.example.com/users").queryParam("page", 1).queryParam("size", 20).build();String url = uriComponents.toUriString();
ResponseEntity<User[]> response = restTemplate.getForEntity(url, User[].class);

3. 處理文件上傳
使用?MultiValueMap?和?HttpEntity:

MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource(new File("path/to/file.jpg")));
body.add("name", "test-file");HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
String url = "https://api.example.com/upload";ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);

六、異常處理


RestTemplate?在遇到 HTTP 錯誤(4xx/5xx)時會拋出異常:

HttpClientErrorException:4xx 客戶端錯誤
HttpServerErrorException:5xx 服務器錯誤
ResourceAccessException:網絡連接錯誤
使用 try-catch 塊捕獲并處理異常:

try {User user = restTemplate.getForObject(url, User.class, 999);
} catch (HttpClientErrorException e) {if (e.getStatusCode() == HttpStatus.NOT_FOUND) {System.out.println("用戶不存在");} else if (e.getStatusCode() == HttpStatus.UNAUTHORIZED) {System.out.println("未授權訪問");}System.out.println("錯誤響應體: " + e.getResponseBodyAsString());
} catch (HttpServerErrorException e) {System.out.println("服務器內部錯誤: " + e.getStatusCode());
} catch (ResourceAccessException e) {System.out.println("網絡連接失敗: " + e.getMessage());
}

七、自定義配置


1. 注冊消息轉換器

RestTemplate restTemplate = new RestTemplate();
// 添加 JSON 消息轉換器(默認使用 Jackson)
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
// 添加 XML 消息轉換器
restTemplate.getMessageConverters().add(new Jaxb2RootElementHttpMessageConverter());

2. 配置超時

使用?SimpleClientHttpRequestFactory:SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(5000); // 連接超時 5 秒
requestFactory.setReadTimeout(5000); ? ?// 讀取超時 5 秒RestTemplate restTemplate = new RestTemplate(requestFactory);


3. 配置錯誤處理器

自定義?ResponseErrorHandler:restTemplate.setErrorHandler(new ResponseErrorHandler() {@Overridepublic boolean hasError(ClientHttpResponse response) throws IOException {return response.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR|| response.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR;}@Overridepublic void handleError(ClientHttpResponse response) throws IOException {// 自定義錯誤處理邏輯if (response.getStatusCode() == HttpStatus.NOT_FOUND) {throw new MyResourceNotFoundException("資源未找到");}}
});


八、使用示例


1. 完整的 GET 請求示例

RestTemplate restTemplate = new RestTemplate();
String url = "https://api.github.com/users/{username}";try {ResponseEntity<User> response = restTemplate.exchange(url,HttpMethod.GET,null,User.class,"octocat");if (response.getStatusCode() == HttpStatus.OK) {User user = response.getBody();System.out.println("用戶名: " + user.getLogin());System.out.println("ID: " + user.getId());}
} catch (HttpClientErrorException e) {System.out.println("GitHub API 錯誤: " + e.getStatusCode());
} catch (Exception e) {System.out.println("發生異常: " + e.getMessage());
}

2. 完整的 POST 請求示例

// 創建請求對象
Map<String, String> requestBody = new HashMap<>();
requestBody.put("title", "foo");
requestBody.put("body", "bar");
requestBody.put("userId", "1");// 設置請求頭
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);// 創建 HttpEntity 對象
HttpEntity<Map<String, String>> request = new HttpEntity<>(requestBody, headers);// 發送 POST 請求
RestTemplate restTemplate = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts";ResponseEntity<Post> response = restTemplate.exchange(url,HttpMethod.POST,request,Post.class
);// 處理響應
if (response.getStatusCode() == HttpStatus.CREATED) {Post createdPost = response.getBody();System.out.println("創建的帖子 ID: " + createdPost.getId());
}

九、替代方案


從 Spring 5 開始,推薦使用?WebClient?替代?RestTemplate,因為它支持響應式編程和非阻塞 I/O:

WebClient webClient = WebClient.create();// 異步 GET 請求示例
Mono<User> userMono = webClient.get().uri("https://api.example.com/users/{id}", 123).retrieve().bodyToMono(User.class);

// 訂閱并處理結果

userMono.subscribe(user -> System.out.println("用戶: " + user.getName()));

十、總結


RestTemplate?是 Spring 框架中處理 REST API 的經典工具,適合同步、阻塞的 HTTP 通信場景。它提供了簡潔的 API 和強大的消息轉換機制,能大幅簡化與外部服務的交互。不過,對于高并發場景,建議使用更現代的?WebClient。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915311.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915311.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915311.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

異步解決一切問題 |消息隊列 |減少嵌套 |hadoop |rabbitmq |postsql

設計準則“為什么要考慮這個問題”The forward logic is only about 10% of your code, everything else is 90%.主流邏輯 10%保障擴容和穩健的代碼設計90%同步代碼就是綁在一個繩上的螞蚱異步就是實現了解耦這個異步或許有點類似于--一些分布式數據的處理 設計如何實現的呢?…

Spring AI 項目實戰(十八):Spring Boot + AI + Vue3 + OSS + DashScope 實現高效語音識別系統(附完整源碼)

系列文章 序號 文章名稱 1 Spring AI 項目實戰(一):Spring AI 核心模塊入門 2 Spring AI 項目實戰(二):Spring Boot + AI + DeepSeek 深度實戰(附完整源碼) 3 Spring AI 項目實戰(三):Spring Boot + AI + DeepSeek 打造智能客服系統(附完整源碼) 4

指針數組和數組指針的應用案例

1. 指針數組應用&#xff1a;查找最長字符串用指針數組存儲若干字符串&#xff0c;編寫函數找出其中最長的字符串&#xff08;若有多個&#xff0c;返回第一個&#xff09;。#include <stdio.h> #include <string.h>// 函數原型&#xff1a;找出最長字符串 const c…

MCU進入低功耗模式前的引腳處理原則和方法 --> 以最小化低功耗電流

在MCU進入低功耗模式(如Sleep, Stop, Standby, Deep Sleep等)前,精心處理每一個GPIO引腳的狀態是最大限度降低功耗電流的關鍵一步。懸空或配置不當的引腳是導致“漏電”的常見原因。以下是處理引腳以達到最小低功耗電流的原則和方法: ?? 核心原則 避免浮空輸入: 浮空(…

張 關于大語言模型(LLM)置信度研究的經典與前沿論文 :溫度縮放;語義熵;自一致性;事實與反思;檢索增強;黑盒引導;

關于大語言模型(LLM)置信度研究的經典與前沿論文 :溫度縮放;語義熵;自一致性;事實與反思;檢索增強;黑盒引導; 目錄 關于大語言模型(LLM)置信度研究的經典與前沿論文 :溫度縮放;語義熵;自一致性;事實與反思;檢索增強;黑盒引導; 一、校準方法:讓模型概率更貼近真實正確…

ICT測試原理之--什么是假短

ICT測試原理之–什么是假短 文章目錄ICT測試原理之--什么是假短一、假短的由來防止假短二、無法檢測的短路示例解決無法檢測的短路調試短路文件調試意外斷路調試意外短路三、調試假短報告短路和斷路報告假短報告短路設備/引腳功能性短路測試功能性短路測試的語法一、假短的由來…

三種深度學習模型(LSTM、CNN-LSTM、貝葉斯優化的CNN-LSTM/BO-CNN-LSTM)對北半球光伏數據進行時間序列預測

代碼功能 該代碼實現了一個光伏發電量預測系統&#xff0c;采用三種深度學習模型&#xff08;LSTM、CNN-LSTM、貝葉斯優化的CNN-LSTM&#xff09;對北半球光伏數據進行時間序列預測&#xff0c;并通過多維度評估指標和可視化對比模型性能。 算法步驟 1. 數據預處理 數據導入&am…

Typecho+阿里云CDN完整配置:防止DDoS攻擊與IP暴露

文章目錄 Typecho使用阿里云CDN保護網站真實IP地址的完整指南 背景與問題分析 技術選型與方案設計 詳細實施步驟 第一步:阿里云CDN基礎配置 第二步:DNS解析設置 第三步:源站服務器防護配置 Nginx服務器配置 防火墻配置(以Ubuntu為例) 第四步:Typecho配置調整 高級防護措施…

[硬件]運算放大器對相位噪聲的影響與設計提示

運算放大器對相位噪聲的影響與設計提示 文章目錄運算放大器對相位噪聲的影響與設計提示運放影響位噪聲的主要因素如何最小化運放對相位噪聲的影響總結運算放大器是常用的模擬電路元器件&#xff0c;通常用于放大信號&#xff0c;增強驅動。但是當使用運放放大一個信號時&#x…

github jekyll+chirpy主題搭建博客

github jekyllchirpy主題搭建博客 標簽&#xff1a;后端、blog、jekyll 全文鏈接 本文簡要介紹了如何基于 GitHub Pages、Jekyll 及 Chirpy 主題搭建個人博客的流程和注意事項。 主要內容 GitHub Pages 站點簡介 可免費搭建個人博客&#xff0c;支持自定義域名&#xff0c;適…

Flutter狀態管理篇之ValueNotifier(三)

目錄 前言 一、ValueNotifier 概述 二、ValueNotifier 的實現原理 1.類定義 1.類定義 2.關鍵字段 3.關鍵方法 1.構造函數 2.getter:value 3.setter:value: 4.toString 2.繼承自ChangeNotifier的機制 3.ValueListenable 接口 三、ValueNotifier 的用法 1.基本用法…

Ubuntu togo 系統安裝指南

制作一個 “Ubuntu To Go” 系統&#xff08;也就是一個可以隨身攜帶、在不同電腦上啟動并擁有持久化存儲的U盤系統&#xff09;是解決你問題的完美方案。 這樣一來&#xff0c;你就可以&#xff1a; 不改動你現有的電腦系統 (保留你的Ubuntu 20.04 或 Windows)。擁有一個完整…

Python爬蟲實戰:研究pefile庫相關技術

一、引言 可執行文件(Portable Executable,PE)是 Windows 操作系統中最常見的文件格式,包括.exe、.dll、.sys 等多種類型。對 PE 文件的分析在軟件逆向工程、惡意軟件檢測、系統安全研究等領域具有重要意義。傳統的 PE 文件分析主要依賴手動操作和專業工具,效率較低且對分…

盟接之橋說制造:差異化定位與效率競爭的雙輪驅動

在當今競爭日益激烈的商業環境中&#xff0c;企業如何在市場中脫穎而出&#xff0c;既避免陷入同質化的價格戰&#xff0c;又能夠通過效率提升實現可持續發展&#xff0c;是每一個經營者必須思考的問題。本文將圍繞“差異化”與“效率競爭”兩大核心戰略展開分析&#xff0c;探…

Vue基礎(前端教程①-路由)

項目結構src/├── router/│ └── index.js # 路由配置├── components/│ ├── Home.vue # 首頁組件│ ├── About.vue # 關于頁組件│ └── Contact.vue # 聯系頁組件├── App.vue # 根組件&#xff08;含導航欄&…

駕馭 Spring Boot 事件機制:8 個內置事件 + 自定義擴展實戰

駕馭 Spring Boot 事件機制&#xff1a;8 個內置事件 自定義擴展實戰在 Spring Boot 應用的完整生命周期中&#xff0c;框架為我們預埋了 8 個關鍵事件&#xff08;Application-level & Context-level&#xff09;。 理解并善用這些事件&#xff0c;可以在“不侵入框架、…

【kafka4源碼學習系列】kafka4總體架構介紹

二 kafka架構介紹學習一個系統之前很重要的一點就是先了解這個系統整體的架構&#xff0c;這能夠使我們對整個系統有個總體的認識&#xff0c;清楚地知道這個系統有什么能力。這不僅幫助我們學習時快速定位到我們想要的內容&#xff0c;還能避免我們學習過程中在龐大的系統中迷…

java內存圖

java內存圖java文件運行流程程序的內存空間認識虛擬機棧程序的執行流程認識堆java的類與對象的關系java文件運行流程 有這樣的一份 java 文件 在該目錄下的終端運行 javac Hello.java 命令&#xff0c;會生成 Hello.class 文件&#xff0c;內容如下&#xff1a; Hello.java 打…

vscode編輯Markdown文件

一.安裝Markdown的插件 vscode的擴展&#xff0c;搜索Markdown Preview Enhanced的插件&#xff0c;并安裝。 其他的常用插件&#xff0c;還包括&#xff1a; Markdown All in One &#xff1a;提供了許多有用的功能&#xff0c;如快捷鍵支持、自動預覽、TOC&#xff08;目錄&…

【PTA數據結構 | C語言版】查找樹中帶有指定數據的結點

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 請編寫程序&#xff0c;創建有 4 個結點的樹&#xff0c;然后查找給定的 x。 輸入格式&#xff1a; 輸入首先在第一行給出 4 個正整數&#xff0c;依次對應樹的根結點、根的第 1、2、3 個孩子結點的…