前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >springboot实战之常用http客户端整合

springboot实战之常用http客户端整合

作者头像
lyb-geek
发布2019-11-12 15:13:18
7.4K0
发布2019-11-12 15:13:18
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路
前言

本文主要介绍一下三种http客户端,httpcomponents项目下的httpclient(后边简化描述为httpcomponents-client)、restTemplate、webclient的基本用法

正文

httpcomponents-client

HttpComponents 也就是以前的httpclient项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端/服务器编程工具包,并且它支持 HTTP 协议最新的版本和建议。

HttpComponents项目下的HttpClient是为扩展而设计的,同时提供了对基本HTTP协议的强大支持,对于构建HTTP感知的客户端应用程序(例如Web浏览器,Web服务客户端或利用或扩展HTTP协议进行分布式通信的系统)

httpcomponents-client特点

  • 基于标准的纯Java,HTTP版本1.0和1.1的实现
  • 在可扩展的OO框架中完全实现所有HTTP方法(GET,POST,PUT,DELETE,HEAD,OPTIONS和TRACE)。
  • 支持使用HTTPS(基于SSL的HTTP)协议进行加密。
  • 通过HTTP代理的透明连接。
  • 通过CONNECT方法通过HTTP代理建立的隧道HTTPS连接。
  • Basic, Digest,NTLMv1,NTLMv2,NTLM2会话,SNPNEGO,Kerberos身份验证方案。
  • 自定义身份验证方案的插件机制。
  • 可插拔的安全套接字工厂,使使用第三方解决方案更加容易
  • 支持在多线程应用程序中使用的连接管理。支持设置最大总连接数以及每个主机的最大连接数。检测并关闭陈旧的连接。
  • 自动Cookie处理
  • 自定义Cookie策略的插件机制。
  • 请求输出流,以避免通过直接流到服务器的套接字来缓冲任何内容主体。
  • 响应输入流通过直接从套接字流传输到服务器来有效地读取响应主体。
  • 在HTTP / 1.0中使用KeepAlive的持久连接以及在HTTP / 1.1中的持久性
  • 直接访问服务器发送的响应代码和header。
  • 设置连接超时的能力。
  • 支持HTTP / 1.1响应缓存。

springboot与httpcomponents-client整合例子

这边提供一个httpcomponents-client工具类

1、pom.xml

代码语言:javascript
复制
<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

2、创建httpcomponents-client配置类

代码语言:javascript
复制
@Configuration
@ConfigurationProperties(prefix = "httpclient")
@Data
public class HttpClientConfig {

    private Integer maxTotal;

    private Integer defaultMaxPerRoute;
    private Integer connectTimeout;

    private Integer connectionRequestTimeout;

    private Integer socketTimeout;

    /**
     * HttpClient连接池
     * @return
     */
    @Bean
    public HttpClientConnectionManager httpClientConnectionManager() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(maxTotal);
        connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return connectionManager;
    }

    /**
     * 创建RequestConfig
     * @return
     */
    @Bean
    public RequestConfig requestConfig() {
        return RequestConfig.custom().setConnectTimeout(connectTimeout)
            .setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout)
            .build();
    }

    /**
     * 创建HttpClient
     * @param manager
     * @param config
     * @return
     */
    @Bean
    public CloseableHttpClient httpClient(HttpClientConnectionManager manager, RequestConfig config) {
        return HttpClientBuilder.create().setConnectionManager(manager).setDefaultRequestConfig(config)
            .build();
    }
}

3、httpcomponents-client工具类

代码语言:javascript
复制
@Component
@Slf4j
public class HttpClientUtil {

    @Autowired
    private CloseableHttpClient httpClient;

    public  String doGet(String url, Map<String, String> param,Map<String,String> headers) {

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            builder.setCharset(Charset.forName("utf-8"));
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            if(headers!= null && !headers.isEmpty()){
                headers.forEach((name,value)->httpGet.setHeader(name,value));
            }

            // 执行请求
            response = httpClient.execute(httpGet);
           return EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                close(response);
                httpClient.close();
            } catch (IOException e) {
               log.error("doGet url:"+url+" fail,cause :"+e.getMessage(),e);
            }
        }
        return resultString;
    }

    public  String doGet(String url) {
        return doGet(url, null,null);
    }

    public  String doPost(String url, Map<String, String> param,Map<String,String> headers) {
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList,Charset.forName("UTF-8"));
                httpPost.setEntity(entity);
            }

            if(headers!= null && !headers.isEmpty()){
                headers.forEach((name,value)->httpPost.setHeader(name,value));
            }

            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            log.error("doPost url:"+url+" fail,cause :"+e.getMessage(),e);
        } finally {
            close(response);
        }

        return resultString;
    }

    private void close(CloseableHttpResponse response) {
        try {
            if(response != null){
                response.close();
            }
        } catch (IOException e) {
         log.error(e.getMessage(),e);
        }
    }

    public  String doPost(String url) {
        return doPost(url, null,null);
    }

    public  String doPostJson(String url, String json) {
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            log.error("doJson url:"+url+" fail,cause :"+e.getMessage(),e);
        } finally {
            close(response);
        }

        return resultString;
    }
}

ps:这个工具类是取自博主海恋北斗星的博文--HttpClientUtil-工具类,其链接如下

https://blog.csdn.net/zy12306/article/details/88554663

我在其工具类的基础上补充了header传值以及表单提交中文产生乱码问题修复,并注入spring

小结

这边没有对httpcomponents-client的方法进行描述,主要是因为httpcomponents-client属于工具类范畴,具体使用可以参考我这边提供的工具类实现就可以,开箱即用。如果想对httpcomponents-client进一步了解,可以访问如下链接

http://hc.apache.org/httpcomponents-client-ga/

restTemplate

spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接,大大提高客户端的编写效率。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。

springboot与restTemplate整合例子

这边提供一个restTemplate工具类

1、pom.xml

代码语言:javascript
复制
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2、创建restTemplate配置类

RestTemplate默认依赖JDK提供的HttpURLConnection,如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。我这边就是使用 Apache HttpComponents,其核心配置如下

代码语言:javascript
复制
@Bean
    public ClientHttpRequestFactory requestFactory(CloseableHttpClient httpClient) {
        return new HttpComponentsClientHttpRequestFactory(httpClient);
    }

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory) {
        RestTemplate template = new RestTemplate(requestFactory);

        List<HttpMessageConverter<?>> list = template.getMessageConverters();
        for (HttpMessageConverter<?> mc : list) {
            if (mc instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) mc).setDefaultCharset(Charset.forName("UTF-8"));
            }
        }
        return template;
    }

3、restTemplate工具类

代码语言:javascript
复制
@Component
public class RestTemplateUtil {

    @Autowired
    private  RestTemplate restTemplate;



    // ----------------------------------GET-------------------------------------------------------

    /**
     * GET请求调用方式
     *
     * @param url 请求URL
     * @param responseType 返回对象类型
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, Class<T> responseType) {
        return restTemplate.getForEntity(url, responseType);
    }

    /**
     * GET请求调用方式
     *
     * @param url 请求URL
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, Class<T> responseType, Object... uriVariables) {
        return restTemplate.getForEntity(url, responseType, uriVariables);
    }

    /**
     * GET请求调用方式
     *
     * @param url 请求URL
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, Class<T> responseType, Map<String, ?> uriVariables) {
        return restTemplate.getForEntity(url, responseType, uriVariables);
    }

    /**
     * 带请求头的GET请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType, Object... uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return get(url, httpHeaders, responseType, uriVariables);
    }

    /**
     * 带请求头的GET请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType, Object... uriVariables) {
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的GET请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return get(url, httpHeaders, responseType, uriVariables);
    }

    /**
     * 带请求头的GET请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
    }

    // ----------------------------------POST-------------------------------------------------------

    /**
     * POST请求调用方式
     *
     * @param url 请求URL
     * @param responseType 返回对象类型
     * @return
     */
    public  <T> ResponseEntity<T> post(String url, Class<T> responseType) {
        return restTemplate.postForEntity(url, HttpEntity.EMPTY, responseType);
    }

    /**
     * POST请求调用方式
     *
     * @param url 请求URL
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType) {
        return restTemplate.postForEntity(url, requestBody, responseType);
    }

    /**
     * POST请求调用方式
     *
     * @param url 请求URL
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
        return restTemplate.postForEntity(url, requestBody, responseType, uriVariables);
    }

    /**
     * POST请求调用方式
     *
     * @param url 请求URL
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        return restTemplate.postForEntity(url, requestBody, responseType, uriVariables);
    }

    /**
     * 带请求头的POST请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return post(url, httpHeaders, requestBody, responseType, uriVariables);
    }

    /**
     * 带请求头的POST请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return post(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的POST请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return post(url, httpHeaders, requestBody, responseType, uriVariables);
    }
    /**

     * 带请求头的POST请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return post(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 自定义请求头和请求体的POST请求调用方式
     *
     * @param url 请求URL
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
        return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
    }

    /**
     * 自定义请求头和请求体的POST请求调用方式
     *
     * @param url 请求URL
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
        return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
    }

    // ----------------------------------PUT-------------------------------------------------------

    /**
     * PUT请求调用方式
     *
     * @param url 请求URL
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, Class<T> responseType, Object... uriVariables) {
        return put(url, HttpEntity.EMPTY, responseType, uriVariables);
    }

    /**
     * PUT请求调用方式
     *
     * @param url 请求URL
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
        return put(url, requestEntity, responseType, uriVariables);
    }

    /**
     * PUT请求调用方式
     *
     * @param url 请求URL
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
        return put(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的PUT请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return put(url, httpHeaders, requestBody, responseType, uriVariables);
    }

    /**
     * 带请求头的PUT请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return put(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的PUT请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return put(url, httpHeaders, requestBody, responseType, uriVariables);
    }

    /**
     * 带请求头的PUT请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return put(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 自定义请求头和请求体的PUT请求调用方式
     *
     * @param url 请求URL
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
        return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables);
    }

    /**
     * 自定义请求头和请求体的PUT请求调用方式
     *
     * @param url 请求URL
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
        return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables);
    }

    // ----------------------------------DELETE-------------------------------------------------------

    /**
     * DELETE请求调用方式
     *
     * @param url 请求URL
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Class<T> responseType, Object... uriVariables) {
        return delete(url, HttpEntity.EMPTY, responseType, uriVariables);
    }

    /**
     * DELETE请求调用方式
     *
     * @param url 请求URL
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Class<T> responseType, Map<String, ?> uriVariables) {
        return delete(url, HttpEntity.EMPTY, responseType, uriVariables);
    }

    /**
     * DELETE请求调用方式
     *
     * @param url 请求URL
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
        return delete(url, requestEntity, responseType, uriVariables);
    }

    /**
     * DELETE请求调用方式
     *
     * @param url 请求URL
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
        return delete(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Class<T> responseType, Object... uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Class<T> responseType, Object... uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
        return delete(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
        return delete(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, requestBody, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return delete(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return delete(url, httpHeaders, requestBody, responseType, uriVariables);
    }

    /**
     * 带请求头的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param headers 请求头参数
     * @param requestBody 请求参数体
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
        HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
        return delete(url, requestEntity, responseType, uriVariables);
    }

    /**
     * 自定义请求头和请求体的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
        return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables);
    }

    /**
     * 自定义请求头和请求体的DELETE请求调用方式
     *
     * @param url 请求URL
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
        return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables);
    }

    // ----------------------------------通用方法-------------------------------------------------------

    /**
     * 通用调用方式
     *
     * @param url 请求URL
     * @param method 请求方法类型
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,按顺序依次对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
        return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
    }

    /**
     * 通用调用方式
     *
     * @param url 请求URL
     * @param method 请求方法类型
     * @param requestEntity 请求头和请求体封装对象
     * @param responseType 返回对象类型
     * @param uriVariables URL中的变量,与Map中的key对应
     * @return ResponseEntity 响应对象封装类
     */
    public  <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
        return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
    }
}

ps:该工具类取自博主诚信天下博文--Spring 远程调用工具类RestTemplateUtils,其链接如下

https://www.cnblogs.com/jonban/p/rest.html

该工具类就是对restTmplate进行浅浅的封装一层,因为restTemplate的http远程调用,基本上也是一两句代码,如果对restemplate的相关API感兴趣的朋友,可以查看如下链接

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

webclient

webClient是一个响应式客户端,它提供了restTemplate的替代方法。它公开了一个功能齐全、流畅的api,并依赖于非阻塞I / O,使其能够比restTemplate更高效地支持高并发性。webclient非常适合流式的传输方案,并且依赖于较低级别的HTTP客户端库来执行请求,是可插拔的。

webclient特点

  • 非阻塞,Reactive的,并支持更高的并发性和更少的硬件资源。
  • 提供利用Java 8 lambdas的函数API。
  • 支持同步和异步方案。
  • 支持从服务器向上或向下流式传输。

springboot与webclient整合

这边提供一个webclient工具类

1、pom.xml

代码语言:javascript
复制
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

2、webclient工具类

代码语言:javascript
复制
@Component
public class WebClientUtil {

    private  final MediaType MEDIATYPE_JSON = MediaType.APPLICATION_JSON_UTF8;

    private  final MediaType MEDIATYPE_FORM = MediaType.APPLICATION_FORM_URLENCODED;

    @Autowired
    private WebClient webClient;

    /**
     *
     * @param paramter
     *            请求参数
     * @param url
     *            请求路径
     * @param resultType
     *            返回结果类型
     * @return
     */
    public  <T> T post(Object paramter, String url, Class<T> resultType) {

        return post(uri(url, HttpMethod.POST), paramter, resultType);
    }

    /**
     *
     * @param paramter
     *            请求参数
     * @param url
     *            请求路径
     * @param header
     *            请求头
     * @param resultType
     *            返回结果类型
     * @return
     */
    public  <T> T post(Object paramter, String url, Map<String, String> header, Class<T> resultType) {

        RequestBodySpec uri = uri(url, HttpMethod.POST);
        addHeader(header, uri);
        return post(uri, paramter, resultType);
    }

    private  <T> T post(RequestBodySpec uri, Object paramter, Class<T> resultType) {

        return uri.contentType(MEDIATYPE_JSON).body(Mono.just(paramter), Object.class).retrieve().bodyToMono(resultType)
                .block();
    }

    /**
     *
     * @param paramter
     *            请求参数
     * @param url
     *            请求路径
     * @param header
     *            请求头
     * @param resultType
     *            返回结果类型
     * @return
     */
    public  <T> T postForm(Map<String,String> paramter, String url, Map<String, String> header, Class<T> resultType) {
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
        formData.setAll(paramter);
        RequestBodySpec uri = uri(url, HttpMethod.POST);
        addHeader(header, uri);
        return postForm(uri, formData, resultType);
    }

    private  <T> T postForm(RequestBodySpec uri, MultiValueMap<String, String> formData , Class<T> resultType) {

        return uri.contentType(MEDIATYPE_FORM).body(BodyInserters.fromFormData(formData)).retrieve().bodyToMono(resultType)
                .block();
    }

    /**
     *
     * @param url
     *            请求路径
     * @param resultType
     *            返回结果类型
     * @return
     */
    public  <T> T get(String url, Class<T> resultType) {

        return uri(url, HttpMethod.GET).retrieve().bodyToMono(resultType).block();
    }

    /**
     *
     * @param url
     *            请求路径
     * @param header
     *            请求头
     * @param resultType
     *            返回结果类型
     * @return
     */
    public  <T> T get(String url, Map<String, String> header, Class<T> resultType) {

        RequestBodySpec uri = uri(url, HttpMethod.GET);
        addHeader(header, uri);
        return uri.retrieve().bodyToMono(resultType).block();
    }

    private  RequestBodySpec uri(String url, HttpMethod method) {

        return webClient.method(method).uri(url);
    }

    private  void addHeader(Map<String, String> header, RequestBodySpec uri) {

        if (!CollectionUtils.isEmpty(header)) {
            header.forEach((name, value) -> uri.cookie(name, value));
        }
    }

}

ps:该工具类取自博主lkw风满楼博文springboot2.0 webClient api调用,其链接如下

https://blog.csdn.net/lkw411526/article/details/79766686

该工具同样也是对webclient进行浅浅的封装一层,因为webclient的http远程调用也是一两句代码。然后该工具原先的博主并没有提供表单提交的实现,我对其进行补充。如果对webclient感兴趣的朋友,可以查看如下链接

https://docs.spring.io/spring/docs/5.1.2.RELEASE/spring-framework-reference/web-reactive.html#webflux-client

以及

https://josdem.io/techtalk/spring/springbootwebclient/

小结

上面提供的工具类,基本上可以满足日常的http远程调用的需求了。下边就再介绍一下,我对这三种工具类进行再次封装实现http调用

自己封装的轮子

1、在启动类上,加上EnableHttpClients注解

代码语言:javascript
复制
@SpringBootApplication(scanBasePackages = "com.github.lybgeek")
@EnableHttpClients(basePackages = "com.github.lybgeek")
public class HttpClientApplication
{
    public static void main( String[] args )
    {

        SpringApplication.run(HttpClientApplication.class,args);
    }
}

2、编写一个业务服务接口

代码语言:javascript
复制
@Remote(url = "http://localhost:8080/api/1.0.0/book",headers = {@RemoteHeader(name = "AccessToken",value = "123456")})
public interface BookService {

  @RemoteRequestMapping(path = "/add")
  BookDTO addBook(BookDTO bookDTO);

  @RemoteRequestMapping(path = "/update",type = HttpclientTypeEnum.REST_TEMPLATE)
  BookDTO editBook(BookDTO bookDTO);

  @RemoteRequestMapping(path = "/del/{id}",type = HttpclientTypeEnum.WEB_CLIENT)
  boolean delBookById(@RemotePathParam(value = "id") Long id);

  @RemoteRequestMapping(path = "/page")
  PageResult<BookDTO> pageBook(PageQuery<BookDTO> pageQuery);

  @RemoteRequestMapping(path = "/list")
  List<BookDTO> listBooks(BookDTO bookDTO);

}

上边的注解,如果使用过springboot开发的朋友,正常都会知道啥意思。这边介绍一下@RemoteRequestMapping中的type,这个type可以用来指定是要使用httpcomponents-client、restTemplate、webClient中的其中一种

3、编写单元测试

代码语言:javascript
复制
@ @Autowired
    private BookService bookService;


    @Test
    public void testAddBook(){
        for(int i = 1; i <= 10; i++){
            BookDTO bookDTO = BookDTO.builder().bookName("python从入门到精通(第"+i+")版")
                    .author("张三"+i).description("python从入门到精通(第"+i+")版,热门系列").price(BigDecimal.valueOf(i*10)).stock(i).build();
            bookDTO = bookService.addBook(bookDTO);
            System.out.println(bookDTO);
        }
    }

    @Test
    public void testUpdateBook(){
        BookDTO bookDTO = BookDTO.builder().id(1L).bookName("图解Http").author("大神").description("http入门系列教程").price(BigDecimal.valueOf(23.2)).stock(1).build();
        bookDTO =  bookService.editBook(bookDTO);
        System.out.println(bookDTO);
    }

    @Test
    public void testDelBook(){
        boolean del = bookService.delBookById(10L);
        Assert.assertTrue(del);
    }

    @Test
    public void testPageBook(){
        PageQuery pageQuery = new PageQuery<>().setPageNo(1).setPageSize(5);
        BookDTO bookDTO = new BookDTO();
        bookDTO.setAuthor("张三");
        //   bookDTO.setBookName("图解Http");
        //   bookDTO.setId(4L);
        pageQuery.setQueryParams(bookDTO);

        PageResult<BookDTO> pageResult = bookService.pageBook(pageQuery);

        if(pageResult != null){
            pageResult.getList().forEach(book -> System.out.println(book));
        }

    }


    @Test
    public void testListBook(){
        BookDTO bookDTO = new BookDTO();
        bookDTO.setAuthor("张三");
        bookDTO.setBookName("java");
        //       bookDTO.setId(5L);
        List<BookDTO> bookDTOS = bookService.listBooks(bookDTO);
        bookDTOS.forEach(book-> System.out.println(book));
    }






}

总结

http客户端的java版调用除了上述的几种,还有很多其他,比如feign等,其次本文的轮子,是以表单提交的方式的调用http,而非采用数据转json再调用。

demo链接

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-httpclient

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正文
    • httpcomponents-client
      • httpcomponents-client特点
        • springboot与httpcomponents-client整合例子
          • 小结
            • restTemplate
              • springboot与restTemplate整合例子
                • webclient
                  • webclient特点
                    • springboot与webclient整合
                      • 小结
                        • 自己封装的轮子
                        • 总结
                        • demo链接
                        相关产品与服务
                        多因子身份认证
                        多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档