RestTemplate Java调用restful接口

news2024/11/17 15:47:23

目录

  • 1. GET请求相关方法
    • (1)getForObject
    • (2)getForEntity
  • 2. POST请求相关
    • 设置请求头和请求体:HttpEntity
    • (1)postForLocation
    • (2)postForObject
    • (3)postForEntity
  • 3. put、delete
  • 4. options 预检请求
  • 5. exchange()万能调用
  • 6. execute()万能调用
  • 7. 获取调用失败的返回体

RestTemplate 一种调用RESTful接口的方式,它简化了与HTTP服务器的通信,并实施了RESTful原则。(拦截器相关有时间整理)

# 使用前说明:

  1. 在新版本springboot中直接使用@Autowired注解注入RestTemplate
  2. 老版本springboot以及spring项目需要手动添加配置,配置如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class WebConfiguration {

	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
}

在需要的类中加入@Autowired RestTemplate 注入成功后就可以调用api来访问三方接口了。

  1. 在RestTemplate类中,不管是get还是post请求都是RestTemplate自己封装的方法,里面调用的都是函数 execute();exectue方法则是调用的包级别的<T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor);如果RestTemplate提供的get和post等相关方法不满足需求,可以调用 execute();
  2. 不管是get、post相关方法还是exectue()方法如果请求失败都会直接抛出throws RestClientException异常,导致无法获取到异常时的响应内容。如果想获取响应内容需要在配置里重写方法,具体配置见 获取调用失败的返回体
  3. RestTemplate默认依赖于标准JDK建立HTTP连接。可以通过setRequestFactory属性切换到使用其他http源,如 Apache HttpComponents, Netty, and OkHttp
  4. RestTemplate中每个HTTP方法都有三个变体,分别是 接受URI模板字符串、URI变量(数组或映射)和 URI 类。通常3种均可,但是如果使用前两种时url参数或模板已经被编码,那么调用后将发生双重编码,建议直接传入 URI 类。

1. GET请求相关方法

(1)getForObject

  • <T> T getForObject() get方法请求,返回泛型T对应响应体中数据。以下是其三个重载方法。

<T> T getForObject(String url, Class<T> responseType, Object... urlVariables) 参数依次为:字符串类型url,T类型响应类型,Object类型url参数
<T> T getForObject(String url, Class<T> responseType, Map<String, ?> urlVariables)字符串类型url,T类型响应类型,Map类型url参数
<T> T getForObject(URI url, Class<T> responseType) URI 以及响应类型

调用示例:(无参调用以及两种url参数调用,URI不作演示,其余方法都相同)

String url = "http://localhost:8080/testGet";
JSONObject responseObj = restTemplate.getForObject(url, JSONObject.class);

String url1 = "http://localhost:8080/testGet1/{1}/{2}";
JSONObject responseObj = restTemplate.getForObject(url1, JSONObject.class, "11", "22");

String url2 = "http://localhost:8080/testGet2?a={param1}&b={param2}";
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("param1", "aaaa");
uriVariables.put("param2", "bbbbb");
JSONObject responseObj = restTemplate.getForObject(url1, JSONObject.class, uriVariables );

(2)getForEntity

  • <T> ResponseEntity<T> getForEntity get请求,返回ResponseEntity类型除响应体外的 头信息、状态码等。方法参数同上。

<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... urlVariables)
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> urlVariables)
<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)

调用示例:

String url = "http://localhost:8080/testGet";
ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(url, JSONObject.class);
JSONObject responseBody =  responseEntity .getBody();// 获取body
HttpStatus statusCode = responseEntity .getStatusCode(); // 状态码
HttpHeaders headers = responseEntity .getHeaders(); // 获取header

2. POST请求相关

设置请求头和请求体:HttpEntity

post系列请求比get请求多了一个Object类型的request参数,比如<T> T postForObject(URI url, Object request, Class<T> responseType)。这个参数一般用HttpEntity<T>来传参。感兴趣的小伙伴可以去源码里看看这个类的几个构造函数。
HttpEntity(T body, MultiValueMap<String, String> headers):
写几个例子:

// 没有headers和body可以直接设置null或者 new HttpEntity();
HttpEntity request = new HttpEntity();

// 只有headers
HttpHeaders headers = new HttpHeaders(); 
headers.setContentType(MediaType.APPLICATION_JSON);
// 也可用MultiValueMap<String, String> headers来创建headers
HttpEntity request = new HttpEntity(headers);

// 只有body
String json = "{\"auth\": \"1111\"}";
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(JSONObject.parseObject(json ));

//headers和body
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(JSONObject.parseObject(requestBody),headers);

组合好请求体就可以调用下面的方法来调接口了。

(1)postForLocation

URI postForLocation() 返回URI,多数场景为返回post添加的数据的URI
三种参数方法:
URI postForLocation(String url, Object request, Object... urlVariables)
URI postForLocation(String url, Object request, Map<String, ?> urlVariables)
URI postForLocation(URI url, Object request)

(2)postForObject

<T> T postForObject 返回响应体
同样,三种参数
<T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
<T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
<T> T postForObject(URI url, Object request, Class<T> responseType)

(3)postForEntity

<T> ResponseEntity<T> postForEntity返回ResponseEntity
三种参数
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType)

post系列这里放一个完整的示例:

String url = "http://localhost:8080/testPost";
HttpHeaders headers = new HttpHeaders(); 
headers.setContentType(MediaType.APPLICATION_JSON);
String json = "{\"auth\": \"1111\"}";
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(JSONObject.parseObject(requestBody),headers);

ResponseEntity<JSONObject> responseObj = restTemplate.postForEntity(url,requestEntity,JSONObject.class);
JSONObject responseBody = responseObj.getBody();

3. put、delete

只列方法,调用参数和以上相同,没有返回值。
void put(String url, Object request, Object... urlVariables)
void put(String url, Object request, Map<String, ?> urlVariables)
void put(URI url, Object request)

void delete(String url, Object... urlVariables)
void delete(String url, Map<String, ?> urlVariables)
void delete(URI url)

4. options 预检请求

返回的是headers.getAllow();
三种调用方法:
Set<HttpMethod> optionsForAllow(String url, Object... urlVariables)
Set<HttpMethod> optionsForAllow(String url, Map<String, ?> urlVariables)
Set<HttpMethod> optionsForAllow(URI url)

5. exchange()万能调用

相对于其他方法,我更喜欢用这个方法来进行一些封装,比较灵活,支持 GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE。返回类型固定为ResponseEntity<T>

具体方法如下:(前两个方法主要是参数Class<T> responseTypeParameterizedTypeReference<T> responseType的不同,每个方法各自有三种url的传递方式,这里只列一种;后两个方法是把请求url和请求体等信息统一封装到RequestEntity类中,看需求和习惯选择调用)。

  • <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)
  • <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Object... uriVariables)
  • <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType)
  • <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)

调用示例:

String url = "http://localhost:8080/testPost";
HttpHeaders headers = new HttpHeaders(); 
headers.setContentType(MediaType.APPLICATION_JSON);
String json = "{\"auth\": \"1111\"}";
HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(JSONObject.parseObject(requestBody),headers);
ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity,JSONObject.class);

6. execute()万能调用

和exchange方法一样,只不过这个方法是所有封装方法的底层调用,返回的是泛型T的响应体对象。

  • <T> T execute(String url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor, Object... urlVariables)
    也有三种url参数调用,不列了。
    调用示例,看源码:
@Override
public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
		Class<T> responseType) throws RestClientException {

	RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType);
	ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
	return execute(url, method, requestCallback, responseExtractor);
}

7. 获取调用失败的返回体

restTemplate默认调用失败时抛出异常 RestClientException,因此正常是无法获取到调用失败时的返回信息,会直接抛出异常。
在这里插入图片描述
比如postman测试调用失败时会返回 :

{
    "error": {
        "message": "Tenant [6d16e50f0cf142b398cbb643cb78be51] token is expired. ",
        "code": "Common.0013"
    }
}

想获取内容需要设置一下 restTemplate类的errorHandler。
在这里插入图片描述
具体操作:之前注入bean时新增如下:

import java.io.IOException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

@Configuration
public class WebConfiguration {

	@Bean
	public RestTemplate restTemplate() {
		RestTemplate restTemplate = new RestTemplate();
		restTemplate.setErrorHandler(new getErrorBodyHandler());
		return restTemplate;
	}
	
	public static class getErrorBodyHandler implements ResponseErrorHandler{
		@Override
		public boolean hasError(ClientHttpResponse response) throws IOException {
			return false;
		}
		@Override
		public void handleError(ClientHttpResponse response) throws IOException {
		}
	}
}

调用示例:

ResponseEntity<Object> responeEntity =  restTemplate.postForEntity(url, requestEntity, Object.class);
HttpStatus httpStatus = responeEntity.getStatusCode();
			
if (HttpStatus.OK.equals(httpStatus) || HttpStatus.CREATED.equals(httpStatus)) {
	HttpHeaders responseHeaders =  responeEntity.getHeaders();
	String token = responseHeaders.get("X-Subject-Token").get(0);
				
	if (!StringUtils.isBlank(token)) {
			tokenString = token;
			return tokenString;
		}
	} else {
	// 调用失败
		LinkedHashMap<String, String> errorHashMap =  (LinkedHashMap<String, String>)requestEntity.getBody().get("error");
		logger.error(errorHashMap.get("message")+","+errorHashMap.get("code"));
	}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/380986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pyqt实现聊天机器人

环境要求 通过调用openai接口实现聊天机器人功能&#xff0c;支持各种参数得调整&#xff0c;文章末尾有各个参数得说明 python3.9pyqt5环境安装 pip install pyqt5 pip install openai pip install pyinstaller源码如下&#xff1a; chat.py import sys from PyQt5.QtWid…

Cortex-A7中断控制器GIC

Cortex-A7中断控制器GIC 中断号 芯片内部的中断都会引起IRQ InterruptGIC将所有的中断源(最多1020个中断ID)分为三类: SPI(SharedPeripheralInterrupt)共享中断&#xff0c;外部中断都属于SPI中断 [ID32-1019]PPI(PrivatePeripheralInterrupt)私有中断 [ID16-31]SGI(Software-…

【MySQL】基础操作:登录、访问、退出和卸载

一、MySQL简介 MySQL数据库最初是由瑞典MySQL AB公司开发&#xff0c;2008年1月16号被Sun公司收购。2009年&#xff0c;SUN又被Oracle收购。MySQL是目前IT行业最流行的开放源代码的数据库管理系统&#xff0c;同时它也是一个支持多线程、高并发、多用户的关系型数据库管理系统。…

亚马逊物流仓库配送延误,美国暴风雪造成损失严重!

美国拉响暴风雪警报&#xff0c;物流配送大面积延误 去年年底&#xff0c;美国的暴风雪给卖家带来的阴影还没有散去。在这本该春暖百花开的季节&#xff0c;暴风雪天气又回到了美国&#xff0c;这次的破坏力比去年年底的有过之而无不及。 当地2月22日&#xff0c;暴风雪在美国…

环境搭建01-Ubuntu16.04如何查看显卡信息及安装NVDIA显卡驱动

1. 查看显卡型号、驱动 ubuntu-drivers devices2. 安装NVIDIA显卡驱动 &#xff08;1&#xff09;验证是否禁用nouveau lsmod | grep nouveau若有输出&#xff0c;没有禁用&#xff0c;进行以下操作禁用。 sudo gedit /etc/modprobe.d/blacklist.conf在文件末尾中添加两条&…

从一个实例配置引入Prometheus的PromQL语法

1. PromQL介绍 PromQL提供对时间序列数据进行逻辑运算、过滤、聚合的支持。应用于数据查询、可视化、告警处理 2. 基本用法 2.1 查询时间序列 点击Prometheus图标,进行查询页面。可以点击地图图标查看有哪些metrics name。输入要查询的metrics name和过滤条件,然后点击执行…

数字逻辑基础:原码、反码、补码

时间紧、不理解可以只看这里的结论 正数的原码、反码、补码相同。等于真值对应的机器码。 负数的原码等于机器码&#xff0c;反码为原码的符号位不变&#xff0c;其余各位按位取反。补码为反码1。 三种码的出现是为了解决计算问题并简化电路结构。 在原码和反码中&#xff0c;存…

C语言 入门教程||C语言 指针||C语言 字符串

C语言 指针 学习 C 语言的指针既简单又有趣。通过指针&#xff0c;可以简化一些 C 编程任务的执行&#xff0c;还有一些任务&#xff0c;如动态内存分配&#xff0c;没有指针是无法执行的。所以&#xff0c;想要成为一名优秀的 C 程序员&#xff0c;学习指针是很有必要的。 …

湖北某灌区量测水监测系统-案例分享

应用背景湖北某灌区是当地主要的粮棉油产区&#xff0c;由于运行多年&#xff0c;渠系工程老化&#xff0c;阻水现象严重&#xff0c;造成了大量水资源浪费。该灌区2019年对渠道进行疏挖、清淤、衬砌&#xff0c;解决输水不畅等问题&#xff0c;2022年启动灌区续建配套与节水改…

Netty核心功能以及线程模型

目录 Netty核心功能以及线程模型 Netty初探 Netty的使用场景&#xff1a; Netty通讯示例 Netty线程模型 Netty模块组件 Netty核心功能以及线程模型 Netty初探 NIO 的类库和 API 繁杂&#xff0c; 使用麻烦&#xff1a; 需要熟练掌握Selector、 ServerSocketChannel、 So…

wepack4配置入门

一、 webpack 简介 1.1 webpack 是什么 webpack是一种前端资源构建工具&#xff0c;一个静态模块打包器(module bundler)。 在 webpack 看来, 前端的所有资源文件(js/json/css/img/less/...)都会作为模块处理。 它将根据模块的依赖关系进行静态分析&#xff0c;打包生成对应的…

机器学习100天(三十二):032 KD树的构造和搜索

机器学习100天,今天讲的是:KD树的构造和搜索! 《机器学习100天》完整目录:目录 在 K 近邻算法中,我们计算测试样本与所有训练样本的距离,类似于穷举法。如果数据量少的时候,算法运行时间没有大的影响,但是如果数据量很大,那么算法运行的时间就会很长。这在实际的应用…

GFD563A101 3BHE046836R0101

GFD563A101 3BHE046836R0101关于高端涂布机张力控制系统方案的介绍高端涂布机张力控制系统方案涂布机是将具有某种功效的胶&#xff0c;或者油墨类物质均匀粘连在塑料薄膜、铝箔、纺织品等表面的机械设备。本系统从放卷到收卷共采用七台变频器&#xff0c;其中收放卷采用闭环张…

Databend 开源周报第 81 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.com 。Whats New探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。Accepted RFCsrfc: 查询结果缓存…

Cartesi 举办的2023 黑客马拉松

Cartesi 是具有 Linux 运行时的特定于应用程序的Rollups执行层。Cartesi 的特定应用程序 Optimistic Rollup 框架使区块链堆栈足够强大&#xff0c;开发人员可以构建计算密集型和以前不可能的去中心化实例。Cartesi 的 RISC-V 虚拟机支持 Linux 运行时环境&#xff0c;允许像你…

DevOps 学习笔记(二)| 使用 Harbor

文章目录1. 上传镜像到 Harbor2. 拉取 Harbor 镜像3. 使用 Jenkins 操作 Harbor1. 上传镜像到 Harbor 首先在CI/CD 服务器中配置 Docker mkdir -p /etc/docker/ cd /etc/docker/ vim daemon.json其中的 IP 地址为Harbor 服务器的 IP 地址 {"xxx": "xxxx"…

IGH主站通信测试csp模式(DC同步 preemrt)连通一从站并实现控制

IGH主站通信测试 linuxcnc配置基础机器人控制LinuxCNC与EtherCAT介绍&&PDO&SDO&#xff0c;搭建环境步骤 需要配置IGH主站的查看这篇文章 linux系统学习笔记7——一次性安装igh-ethercat主站 CSP模式 DC同步方式 preemrt实时补丁 直接上代码&#xff0c;这…

YOLOV7模型调试记录

先前的YOLOv7模型是pytorch重构的&#xff0c;并非官方提供的源码&#xff0c;而在博主使用自己的数据集进行实验时发现效果并不理想&#xff0c;因此生怕是由于源码重构导致该问题&#xff0c;此外还需进行对比实验&#xff0c;因此便从官网上下载了源码&#xff0c;进行调试运…

二叉树——二叉搜索树中的插入操作

二叉搜索树中的插入操作 链接 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c…

配置二层远程端口镜像案例

实验拓扑&#xff1a; 实验需求&#xff1a; 如图1所示&#xff0c;某公司行政部通过SwitchA与外部Internet通信&#xff0c;监控设备Server通过SwitchB与SwitchA相连。 现在希望Server能够远程对行政部访问Internet的流量进行监控。 操作步骤&#xff1a; 配置观察端口 # 在…