Java实现HTTP请求的几种方式-RestTemplate(四)

通过SpringBoot-RestTemplate进行请求

springBoot-RestTemple是上面三种方式的集大成者,代码编写更加简单,目前可以采用的调用第三方接口有:

delete() :在特定的URL上对资源执行HTTP DELETE操作
exchange() :在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的
execute() :在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
getForEntity() :发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
getForObject() :发送一个HTTP GET请求,返回的请求体将映射为一个对象
postForEntity() :POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的
postForObject() :POST 数据到一个URL,返回根据响应体匹配形成的对象
headForHeaders() :发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
optionsForAllow() :发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
postForLocation() :POST 数据到一个URL,返回新创建资源的URL
put() :PUT 资源到特定的URL

最常使用的,就是exchange()方法

1.导入springboot的web包

首先导入springboot的web包

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

2.注册bean

注册RestTemplate的bean

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplateBuilder()
                //连接超时
                .setConnectTimeout(Duration.ofMinutes(1))
                //读取超时,可理解为soTimeout
                .setReadTimeout(Duration.ofMinutes(2))
                .build();
    }

3.请求

Post方式

往spring容器中注入restTempate实例,在配置类中加入此Bean

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplateBuilder()
        		//连接超时
                .setConnectTimeout(Duration.ofMinutes(1))
                //读超时
                .setReadTimeout(Duration.ofMinutes(2))
                .build();
    }
postForEntity方法请求

post封装方法(postForEntity)

    /**
     * 以post方式请求第三方http接口 postForEntity
     * 无法设置请求头
     *
     * @param url
     * @return
     */
    public <R> R doPostWith1(String url, Object param, Class<R> returnType) {
        ResponseEntity<R> responseEntity = restTemplate.postForEntity(url, param, returnType);
        R body = responseEntity.getBody();
        return body;
    }

业务方法:

   @SneakyThrows
    public TestHttpAccessResponse sendHttpRequestByRestTemplate() {
        TestHttpAccessRequest request = new TestHttpAccessRequest();
        request.setAge(16);
        request.setName("刘伞");
        request.setAddress("佛山市");

        String httpUrl = "http://localhost:8082/nacos-service-provider/testHttpAccess";

        /**
         * 如果是List<T>这种带泛型的对象,则需要使用TypeReference<类型> typeRef = new TypeReference...
         * 注意日期的类型,需要事前设置类型转换器
         */
        JsonResult jsonResult = restTemplateTestService.doPostWith1(httpUrl, request, JsonResult.class);
        //JsonResult jsonResult = restTemplateTestService.doPostWith2(httpUrl, request, JsonResult.class);
        //JsonResult jsonResult = restTemplateTestService.doExchange(httpUrl, request, JsonResult.class);
        if (Objects.isNull(jsonResult) || !ReturnCode.SUCCESS.getCode().equals(jsonResult.getCode())) {
            if (Objects.isNull(jsonResult)) {
                throw new BizException(ReturnCode.ERROR);
            } else {
                throw new BizException(jsonResult.getCode(), jsonResult.getMessage());
            }
        }
        TestHttpAccessResponse response = objectMapper.convertValue(jsonResult.getData(), TestHttpAccessResponse.class);
        return response;
    }

结果:(原测试接口去掉了token验证部分,否则会出现token验证失败的提示)
在这里插入图片描述

postForObject方法请求
    /**
     * 以post方式请求第三方http接口 postForObject
     * postForObject特点:可以直接返回指定的类型
     * 无法设置请求头
     *
     * @param url
     * @return
     */
    public <R> R doPostWith2(String url, Object param, Class<R> returnType) {
        R response = restTemplate.postForObject(url, param, returnType);
        return response;
    }

业务方法同postForEntity

结果:(原测试接口去掉了token验证部分,否则会出现token验证失败的提示)
在这里插入图片描述

exchange方法请求
/**
     * exchange
     * 可设置请求头
     *
     * @return
     */
    public <R> R doExchange(String url, Object param, Class<R> returnType) throws JsonProcessingException {
        //header参数
        HttpHeaders headers = new HttpHeaders();
        //getToken的方法可看上面的例子
        String token = getToken();
        headers.add("Authorization", token);
        headers.setContentType(MediaType.APPLICATION_JSON);

        //放入body中的json参数
        String obj = objectMapper.writeValueAsString(param);

        //组装
        HttpEntity request = new HttpEntity(obj, headers);
        ResponseEntity<R> responseEntity = restTemplate.exchange(url, HttpMethod.POST, request, returnType);
        R body = responseEntity.getBody();
        return body;
    }

业务方法同postForEntity

结果:
在这里插入图片描述

注:这里的连接超时跟CloseableHttpClient有一样的特点,大概20s的时候就会返回ConnectException

Get方式请求

getForEntity方法请求
   public <R> R doGetWith1(String url, Object param, Class<R> returnType) throws IllegalAccessException {
        Class<?> aClass = param.getClass();
        List<String> paramsList =new ArrayList<>();
        if(Objects.nonNull(param)){
            for (Field declaredField : aClass.getDeclaredFields()) {
                declaredField.setAccessible(Boolean.TRUE);
                Object o = declaredField.get(param);
                paramsList.add(declaredField.getName()+"="+o);
            }
            url = url+"?"+paramsList.stream().collect(Collectors.joining("&"));
        }

        //不支持headers设置

        ResponseEntity<R> responseEntity = restTemplate.getForEntity(url, returnType);
        R body = responseEntity.getBody();
        return body;
    }

getForEntity其实还有通过占位符的方式去拼接url参数,不过我这个方法是直接传入整个param对象,而且通过param对象反射生成占位符的方式又很麻烦,还不如直接拼接url参数。
除非是参数量少而且稳定不变化的,就可以按占位符去使用。

getForObject方法请求

跟postForObject类似,可以直接返回指定对象类型

/**
     * 以post方式请求第三方http接口 postForObject
     * postForObject特点:可以直接返回指定的类型
     *
     * @param url
     * @return
     */
    public <R> R doGetWith2(String url, Object param, Class<R> returnType) throws IllegalAccessException {
        Class<?> aClass = param.getClass();
        List<String> paramsList =new ArrayList<>();
        if(Objects.nonNull(param)){
            for (Field declaredField : aClass.getDeclaredFields()) {
                declaredField.setAccessible(Boolean.TRUE);
                Object o = declaredField.get(param);
                paramsList.add(declaredField.getName()+"="+o);
            }
            url = url+"?"+paramsList.stream().collect(Collectors.joining("&"));
        }

        //不支持headers设置

        R response = restTemplate.getForObject(url, returnType);
        return response;
    }
exchange方法请求

与上面post的exchange方式是相同的方法,只不过可以指定POST还是GET。
并且exchange可以支持请求头的设置

 /**
  * exchange
  *
  * @return
  */
 public <R> R doGetExchange(String url, Object param, Class<R> returnType) throws JsonProcessingException, IllegalAccessException {
     Class<?> aClass = param.getClass();
     List<String> paramsList =new ArrayList<>();
     if(Objects.nonNull(param)){
         for (Field declaredField : aClass.getDeclaredFields()) {
             declaredField.setAccessible(Boolean.TRUE);
             Object o = declaredField.get(param);
             paramsList.add(declaredField.getName()+"="+o);
         }
         url = url+"?"+paramsList.stream().collect(Collectors.joining("&"));
     }

     //header参数
     HttpHeaders headers = new HttpHeaders();
     String token = getToken();
     headers.add("Authorization", token);
     headers.setContentType(MediaType.APPLICATION_JSON);


     //组装
     HttpEntity request = new HttpEntity(headers);
     ResponseEntity<R> responseEntity = restTemplate.exchange(url, HttpMethod.GET, request, returnType);
     R body = responseEntity.getBody();
     return body;
 }

结果:
在这里插入图片描述

其他阅读

Java实现HTTP请求的几种方式-HttpURLConnection(一)
Java实现HTTP请求的几种方式-Apache HttpClient(二)
Java实现HTTP请求的几种方式-CloseableHttpClient(三)
Java实现HTTP请求的几种方式-OKHttp(五)

参考

https://mp.weixin.qq.com/s/pLRaZq-_2DVe-1xardJcYA
https://blog.csdn.net/a18262285324/article/details/112470363
https://blog.csdn.net/yangshengwei230612/article/details/103870179

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值