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

  • Post author:
  • Post category:java




通过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



版权声明:本文为ZULJ131原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。