Spring-RestTemplate

前言

Java中常用的Http工具:HttpURLConnection(java.net)、HttpClients(Apache)、OkHttp(安卓常用)、RestTemplate(Spring Web中集成)

使用SpringBoot开发web应用,一般使用RestTemplate,不需要额外引入三方依赖,并且使用方便

Spring Boot Web项目一般需要引用spring boot starter web依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>${spring.boot.version}</version>
</dependency>

其依赖结构图如下,RestTemplate在spring web的jar包中

RestTemplate是按照Rest规范发送Http请求的一个工具类,所以工具类中需要制定接口类型:Get、Post等

常用方法

Get请求

例如发送Get请求,可以使用getForEntity、exchange,getForEntity只能发送Get请求,exchange可以设置请求类型:例如Get、Post等

其中getForEntity包含六种方法

image-20210701102557206

按照接口返回类型:分为两种,一种是返回默认对象ResponseEntity<T>,其中T是接口的具体返回内容;另外一种是自定义的返回类型;一般我们不需要自定义返回类型,所以这里选择前三种方法即可

前三中方法按照接口url类型可以分为两类,一种是字符串类型;另一种是通过URI(java.net)对象构造请求地址;一般使用字符串类型即可

使用字符串url的方法有两个:一种是使用数组类型的参数,数组参数顺序和url中数字序号一致;另外一种是使用Map类型的参数,按照Map中key匹配url中参数名称;具体使用如下

public class NormalTest {
    @Test
    public void printId() {
        RestTemplate restTemplate = new RestTemplate();

        // url中使用{1}数字作为占位符,数字序号对应数组参数中的顺序
        String url = "https://8def7b1e-e53c-41d5-9a62-6189850f699c.mock.pstmn.io/basicInfo/get?name={1}";
        ResponseEntity<JSONObject> hulei = restTemplate.getForEntity(url, JSONObject.class, "zhangsan");
        System.out.println(Optional.ofNullable(hulei.getBody()).map(JSONAware::toJSONString).orElse("null"));

        // url中使用{key}作为占位符,key即Map中key
        String url1 = "https://8def7b1e-e53c-41d5-9a62-6189850f699c.mock.pstmn.io/basicInfo/get?name={name}";
        Map<String, Object> map = new HashMap<>();
        map.put("name", "zhangsan");
        ResponseEntity<JSONObject> hulei1 = restTemplate.getForEntity(url1, JSONObject.class, map);
        System.out.println(Optional.ofNullable(hulei1.getBody()).map(JSONAware::toJSONString).orElse("null"));
    }
}

如果需要携带特殊的请求头,则需要使用exchange方法

exchange方法的六个重载方法如下,这里我们关注前两个方法

image-20210706103006562

下面以第一个方法为例发送get请求,具体如下,请求中可以指定请求头以及请求体参数

@Test
public void testRest(){
    RestTemplate restTemplate = new RestTemplate();

    // 设置请求头,请求头标准字段可以使用setXxx字段设置,自定义请求头可以指定请求头Key字段名称
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    httpHeaders.set("Authorization", "xxx");
    httpHeaders.put(HttpHeaders.COOKIE, new ArrayList<>());

    // 设置请求体,get请求不可以设置请求体,post请求则可以设置请求体
    HashMap<String, String> map = new HashMap<>();
    map.put("name", "zhangsan");
    HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(map, httpHeaders);
    String url1 = "https://8def7b1e-e53c-41d5-9a62-6189850f699c.mock.pstmn.io/basicInfo/get?name={0}";
    // 请求地址,请求方式,请求实体(请求头+请求体参数),响应接受类型,url参数(如果url中存在占位符)
    ResponseEntity<JSONObject> zhangsan = restTemplate.exchange(url1, HttpMethod.GET, httpEntity, JSONObject.class, "zhangsan");
    System.out.println(Optional.ofNullable(zhangsan.getBody()).map(JSONAware::toJSONString).orElse("null"));
}

扩展

并发安全

一般而言,RestTtemplate通过new生成新的对象,生成的实例中存在默认的配置:例如超时响应时间设置等。

对于同一项目中,对于超时响应时间这种基础配置一般有固定值,并且每个项目有自己的固定值;因此一般需要配置一个RestTemplate的Bean,并进行基础参数的配置。如下

@Configuration
public class RestConfig {
    @Bean
    public RestTemplate restTemplate(){
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        // 设置超时时间
        requestFactory.setConnectTimeout(30 * 1000);
        requestFactory.setReadTimeout(30 * 1000);
        return new RestTemplateBuilder()
               .requestFactory(() -> requestFactory)
               .build();
    }
}

对于上述注入Spring的单实例RestTemplate,如果配置中都是公共的参数配置,则不存在并发的问题;

当一个特定的http请求需要设置连接超时时间5s,则不能使用上述注入的实例,否则在使用过程中如果修改了超时配置,则会影响系统中所有使用此RestTempalte实例的请求

代理

RestTemplate工具也支持代理配置,具体配置参考博主另一篇笔记

URI简述

URI: schema://schema specific part, 模式:模式明细

模式即协议,例如:http、https、file、ftp、magnet等

模式明细包含://authority/path?query, authority = ip:port

java.net中可以将字符串url解析为URI对象

@Test
    @SneakyThrows
    public void testURI(){
        // schema://userinfo@authority[host:port]/path?query#fragment
        // 模式://用户信息[账号:密码]@授权主机[ip:port]/路径?路径参数#片段[网页的一部分]
        URI resolve = URI.create("https://zhangsan:admin123@8def7b1e-e53c-41d5-9a62-6189850f699c.mock.pstmn.io:80/basicInfo/get?name=zhangsan#home");
        System.out.println("");
    }

解析出来的URI对象各字段如下

image-20210701115954907

java.net.URI中的构造方法,其中ssp为schema specific part, 其余参数含义参考以上描述

image-20210701115749136

posted @ 2021-07-06 11:27  规划中~~~  阅读(231)  评论(0)    收藏  举报