Spring之RestTemplate简单使用


前言

什么是RestTemplate:

RestTemplate是一个执行HTTP请求的同步阻塞式工具类,它仅仅只是在 HTTP 客户端库(例如 JDK HttpURLConnection,Apache HttpComponents,okHttp 等)基础上,封装了更加简单易用的模板方法 API,方便程序员利用已提供的模板方法发起网络请求和处理,能很大程度上提升我们的开发效率。它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。

本文仅介绍简单的使用方法。


一、环境配置

如果当前项目是SpringBoot,添加如下依赖接口!

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

二、API 实践

1.常用get请求方法

通过RestTemplate发送HTTP GET协议请求,经常使用到的方法有两个:

  • getForObject():返回值是HTTP协议的响应体
  • getForEntity():返回的是ResponseEntity,ResponseEntity是对HTTP响应的封装,除了包含响应体,还包含HTTP状态码、contentType、contentLength、Header等信息

1.1 getForObject()请求示例

  • 不带参数:

(uri, String.class) 这两个参数分别代表 请求地址、HTTP响应转换被转换成的对象类型

String uri = "http://localhost:8080/springTest/template";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
  • 携带参数:

如果是get请求,又想要把参数封装到map里面进行传递的话,Map需要使用HashMap,且uri需要使用占位符
(uri, String.class, paramMap) 这三个参数分别代表 请求地址、HTTP响应转换被转换成的对象类型,请求参数

String uri = "http://localhost:8080/springTest/template?name={name}&age={age}";
RestTemplate restTemplate = new RestTemplate();
// 封装参数,这里是HashMap
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("name", "张三");
paramMap.put("age", "18");
String result = restTemplate.getForObject(uri, String.class, paramMap);

1.2 getForEntity()请求示例

上面的所有的getForObject请求传参方法,getForEntity都可以使用,使用方法上也几乎是一致的,只是在返回结果接收的时候略有差别
getForEntity使用 ResponseEntity<T> responseEntity 来接收响应结果。用responseEntity.getBody()获取响应体

  • 不带参数:
    (uri, String.class) 这两个参数分别代表 请求地址、HTTP响应转换被转换成的对象类型
String uri = "http://localhost:8080/springTest/template";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate .getForEntity(uri, String.class);
// 获取响应体
System.out.println("HTTP 响应body:" + response.getBody().toString());

// 以下是getForEntity比getForObject多出来的内容
HttpStatus statusCode = response.getStatusCode();
int statusCodeValue = response.getStatusCodeValue();
HttpHeaders headers = response.getHeaders();

System.out.println("HTTP 响应状态:" + statusCode);
System.out.println("HTTP 响应状态码:" + statusCodeValue);
System.out.println("HTTP Headers信息:" + headers);
  • 携带参数:
    如果是get请求,又想要把参数封装到map里面进行传递的话,Map需要使用HashMap,且uri需要使用占位符
    (uri, String.class, paramMap) 这三个参数分别代表 请求地址、HTTP响应转换被转换成的对象类型,请求参数
String uri = "http://localhost:8080/springTest/template?name={name}&age={age}";
RestTemplate restTemplate = new RestTemplate();
// 封装参数,这里是HashMap
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("name", "张三");
paramMap.put("age", "18");
ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class, paramMap);

2.常用post请求方法

POST请求方法和GET请求方法上大同小异,RestTemplate的POST请求也包含两个主要方法:

  • postForObject():返回body对象
  • postForEntity():返回全部的信息

postForObject和postForEntity方法的区别主要在于可以在postForEntity方法中设置header的属性,当需要指定header的属性值的时候,使用postForEntity方法。

1、网上都说需要使用MultiValueMap传递参数,但是经过自己测试,发现 MultiValueMap 传递参数请求失败(JSON parse error),改为HashMap反而成功

请求示例

String uri = "http://localhost:8080/springTest/template";
RestTemplate restTemplate = new RestTemplate();

// 使用MultiValueMap调用失败,改用HashMap
// MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
// paramMap.add("name", "张三");
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("name", "张三");

// 1、使用postForObject请求接口
String result = restTemplate.postForObject(uri, paramMap, String.class);

// 2、使用postForEntity请求接口
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("token", "Bearer eyJ0eXAiOiJqd3QiLC.....");

// 使用MultiValueMap调用失败,改用HashMap
// HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(paramMap,headers);
String body = JSONUtil.toJsonStr(paramMap);
HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.postForEntity(uri, httpEntity, String.class);

2、使用这二种方法传递参数,还可以通过JSONObject或者实体类传递参数

请求示例

String uri = "http://localhost:8080/springTest/template";
RestTemplate restTemplate = new RestTemplate();

User user = new User ();
user .setName("张三")

// 1、使用postForObject请求接口
String result = restTemplate.postForObject(uri, user, String.class);

// 2、使用postForEntity请求接口
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("token", "Bearer eyJ0eXAiOiJqd3QiLC.....");

HttpEntity<String> httpEntity = new HttpEntity<String>(JSONUtil.toJsonStr(user),headers);
ResponseEntity<String> response = restTemplate.postForEntity(uri, httpEntity, String.class);

3.通用exchange请求方法

在RestTemplate工具类里面,还有一个exchange通用协议请求方法,exchange方法和postForEntity类似,但是更灵活,它可以发送GET、POST、DELETE、PUT、OPTIONS、PATCH等等HTTP方法请求

RestTemplate.exchange()方法的使用:

方法名称:exchange(String url, HttpMethod method,@Nullable HttpEntity<?> requestEntity, Class responseType, Map uriVariables)
说明:1)url: 请求地址;
     2)method: 请求类型(如:POST,PUT,DELETE,GET)3)requestEntity: 请求实体,封装请求头,请求内容
     4)responseType: 响应类型,根据服务接口的返回类型决定
     5)uriVariables: url中参数变量值

3.1 get请求示例

以下演示传递header和参数的情况,不需要可以传null或不传

String uri = "http://localhost:8080/springTest/template?name={name}&age={age}";
RestTemplate restTemplate = new RestTemplate();

Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("name", "张三");
paramMap.put("age", "18");

HttpHeaders headers = new HttpHeaders();
headers.add("token", "Bearer eyJ0eXAiOiJqd3QiLC.....");
HttpEntity<String> httpEntity = new HttpEntity<>(null, headers);

ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, String.class,paramMap);

//返回数据处理,实体接收
String responseStr = response.getBody();
JSONObject jsonObject = JSON.parseObject(responseStr);
// 返回数据
return StringUtil.isBlank(responseStr) ?
        new Response(500, "返回空数据") :
        JSONObject.toJavaObject(jsonObject, Response.class);

3.2 post请求示例

1、网上都说需要使用MultiValueMap传递参数,但是经过自己测试,发现 MultiValueMap 传递参数请求失败(JSON parse error),改为HashMap反而成功

请求示例:

String uri = "http://localhost:8080/springTest/template";
RestTemplate restTemplate = new RestTemplate();

// 使用MultiValueMap调用失败,改用HashMap
// MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
// paramMap.add("name", "张三");
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("name", "张三");

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("token", "Bearer eyJ0eXAiOiJqd3QiLC.....");

// 使用MultiValueMap调用失败,改用HashMap
// HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(paramMap,headers);
String body = JSONUtil.toJsonStr(paramMap);
HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);

//返回数据处理,实体接收
String responseStr = response.getBody();
JSONObject jsonObject = JSON.parseObject(responseStr);
// 返回数据
return StringUtil.isBlank(responseStr) ?
        new Response(500, "返回空数据") :
        JSONObject.toJavaObject(jsonObject, Response.class);

2、使用这种方法传递参数,和postForEntity类似,还可以通过JSONObject传递参数

String uri = "http://localhost:8080/springTest/template";
RestTemplate restTemplate = new RestTemplate();

User user = new User ();
user .setName("张三")

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("token", "Bearer eyJ0eXAiOiJqd3QiLC.....");

HttpEntity<String> httpEntity = new HttpEntity<String>(JSONUtil.toJsonStr(user),headers);
ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);

//返回数据处理,实体接收
String responseStr = response.getBody();
JSONObject jsonObject = JSON.parseObject(responseStr);
// 返回数据
return StringUtil.isBlank(responseStr) ?
        new Response(500, "返回空数据") :
        JSONObject.toJavaObject(jsonObject, Response.class);

三、https 请求

某些情况下需要进行https请求,需要特殊处理,下面以通用exchange请求方法为例

1.添加依赖

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

2.添加配置

package com.demo.config;

import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContexts;
import org.springframework.http.client.SimpleClientHttpRequestFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.KeyStore;

public class HttpsClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
    @Override
    protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
        try {
            if (connection instanceof HttpsURLConnection) {// https协议,修改协议版本
                KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
                // 信任任何链接,忽略对证书的校验
                TrustStrategy anyTrustStrategy = (x509Certificates, s) -> true;
                //自定义SSLContext
                SSLContext ctx = SSLContexts.custom().loadTrustMaterial(trustStore, anyTrustStrategy).build();
                // ssl问题
                ((HttpsURLConnection) connection).setSSLSocketFactory(ctx.getSocketFactory());
                //解决No subject alternative names matching IP address xxx.xxx.xxx.xxx found问题
                ((HttpsURLConnection) connection).setHostnameVerifier((s, sslSession) -> true);
                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
                super.prepareConnection(httpsConnection, httpMethod);
            } else { // http协议
                super.prepareConnection(connection, httpMethod);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.请求实例

3.1 get请求示例

private Response getApi(String url) {
    try {
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
        // 发送请求
        RestTemplate client = new RestTemplate();
        if (url.contains("https")){
            client = new RestTemplateBuilder()
                    .requestFactory(HttpsClientHttpRequestFactory::new)
                    //basic认证
                    .basicAuthentication("username", "password")
                    .build();
        }
        ResponseEntity<String> response = client.exchange(url, HttpMethod.GET, requestEntity, String.class);
        String responseStr = response.getBody();
        JSONObject jsonObject = JSON.parseObject(responseStr);
        // 返回数据
        return StringUtil.isBlank(responseStr) ?
                new Response(500, "返回空数据") :
                JSONObject.toJavaObject(jsonObject, Response.class);
    } catch (Exception e) {
        log.error("response error:{}", e);
        return new Response(500, e.toString());
    }
}

3.2 post请求示例

private Response postApi(String url, Map<String, Object> paramMap) {
    try {
        // 请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        // 参数信息
        String body = JSONUtil.toJsonStr(paramMap);
        HttpEntity<String> requestEntity = new HttpEntity<>(body, headers);
        // 发送请求
        RestTemplate client = new RestTemplate();
        if (url.contains("https")){
            client = new RestTemplateBuilder()
                    .requestFactory(HttpsClientHttpRequestFactory::new)
                    //basic认证
                    .basicAuthentication("username", "password")
                    .build();
        }
        ResponseEntity<String> response = client.exchange(url, HttpMethod.POST, requestEntity, String.class);
        String responseStr = response.getBody();
        JSONObject jsonObject = JSON.parseObject(responseStr);
        // 返回数据
        return StringUtil.isBlank(responseStr) ?
                new Response(500, "返回空数据") :
                JSONObject.toJavaObject(jsonObject, Response.class);
    } catch (Exception e) {
        log.error("response error:{}", e);
        return new Response(500, e.toString());
    }
}

总结

本文仅仅简单介绍了RestTemplate的使用,而RestTemplate提供了大量能使我们快速便捷地处理Http请求的方法。

  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值