HttpClient入门【简单使用】

发布时间:2023-05-27 19:30

前言:最近项目中用到了httpclient,于是乎去学习了一下,但是在实操过程中发现存在很多的问题,踩了很多坑,所以便想着记录下来,以便自己回顾,同时也希望能够帮助有需要的朋友们。
1.HttpClient介绍
要是不了解咱去就问下百度:HttpClient
2.为什么要用到HttpClient
httpclient的使用范围很广泛,不过在我的知识储备中主要是以下两点:

  • 一、使用httpclient写爬虫
  • 二、项目中远程调用服务(咱今天就好好来唠唠)

3.原因
在项目开发中,需要调用另外一个项目的接口,然鹅这个项目不是微服务的系统,用不了SpringCloud的Fegin,,然后再加上知识有限,于是就想到了使用HttpClient.
4.遇到的问题
开始使用的过程中,没啥问题一路通畅,感觉如鱼得水般,后来发现自己太年轻,然后就遇见了一系列的问题:

  • 传参:对象和map参数如何传递
  • 如何上传文件

5.解决问题
常规操作,导入依赖、yml配置、注入spring



            org.apache.httpcomponents
            httpclient
            4.5.8
 
 

#httpclient自定义属性
http:
  maxTotal: 100 #最大连接数
  defaultMaxPerRoute: 50 #并发数
  connectTimeout: 1000 #创建连接的最长时间
  connectionRequestTimeout: 1000  #从连接池中获取到连接的最长时间
  socketTimeout: 1000 #数据传输的最长时间
  staleConnectionCheckEnabled: true #提交请求前测试连接是否可用

配置配,然后注入spring

@Configuration
public class HttpClient {

    @Value(\"${http.maxTotal}\")
    private Integer maxTotal;

    @Value(\"${http.defaultMaxPerRoute}\")
    private Integer defaultMaxPerRoute;

    @Value(\"${http.connectTimeout}\")
    private Integer connectTimeout;

    @Value(\"${http.connectionRequestTimeout}\")
    private Integer connectionRequestTimeout;

    @Value(\"${http.socketTimeout}\")
    private Integer socketTimeout;

    @Value(\"${http.staleConnectionCheckEnabled}\")
    private boolean staleConnectionCheckEnabled;

    /**
     * 首先实例化一个连接池管理器,设置最大连接数、并发连接数
     *
     * @return
     */
    @Bean(name = \"httpClientConnectionManager\")
    public PoolingHttpClientConnectionManager getHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
        //最大连接数
        httpClientConnectionManager.setMaxTotal(maxTotal);
        //并发数
        httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return httpClientConnectionManager;
    }

    /**
     * 实例化连接池,设置连接池管理器。
     * 这里需要以参数形式注入上面实例化的连接池管理器
     *
     * @param httpClientConnectionManager
     * @return
     */
    @Bean(name = \"httpClientBuilder\")
    public HttpClientBuilder getHttpClientBuilder(@Qualifier(\"httpClientConnectionManager\") PoolingHttpClientConnectionManager httpClientConnectionManager) {

        //HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

        httpClientBuilder.setConnectionManager(httpClientConnectionManager);

        return httpClientBuilder;
    }

    /**
     * 注入连接池,用于获取httpClient
     *
     * @param httpClientBuilder
     * @return
     */
    @Bean
    public CloseableHttpClient getCloseableHttpClient(@Qualifier(\"httpClientBuilder\") HttpClientBuilder httpClientBuilder) {
        return httpClientBuilder.build();
    }

    /**
     * Builder是RequestConfig的一个内部类
     * 通过RequestConfig的custom方法来获取到一个Builder对象
     * 设置builder的连接信息
     * 这里还可以设置proxy,cookieSpec等属性。有需要的话可以在此设置
     *
     * @return
     */
    @Bean(name = \"builder\")
    public RequestConfig.Builder getBuilder() {
        RequestConfig.Builder builder = RequestConfig.custom();
        return builder.setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(connectionRequestTimeout)
                .setSocketTimeout(socketTimeout)
                .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled);
    }

    /**
     * 使用builder构建一个RequestConfig对象
     *
     * @param builder
     * @return
     */
    @Bean
    public RequestConfig getRequestConfig(@Qualifier(\"builder\") RequestConfig.Builder builder) {
        return builder.build();
    }

}

然后就是根据具体的业务操作抽取出一个工具类来,这里我就不贴出来了。接着该解决问题了~
如果你使用的是Post请求,那么有一点一定要注意,那就是数据格式

//JSON格式
post.setHeader(\"Content-Type\", \"application/json;charset=utf8\");
//普通form表单
post.setHeader(\"Content-Type\", \"x-www-form-urlencoded\");
//带文件对象的from表单
post.setHeader(\"Content-Type\", \"multipart/form-data\");
 
//除了在头部设置,也可以在参数对象里面设置
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);

参数为对象的请求(JSON)

    public HttpResult doPostJSON(String url, Object object, String reqHeader) throws Exception {
        // 声明httpPost请求
        HttpPost post = new HttpPost(url);
        // 加入配置信息
        post.setConfig(config);
        post.setHeader(\"Content-Type\", \"application/json;charset=utf8\");
        post.setHeader(\"User-Agent\", reqHeader);
        String result = null;
        HttpResponse resp = null;
        try {
        	//将object转成StringEntity并且设置UTF-8格式
            StringEntity param = new StringEntity(JSONObject.toJSONString(object),\"UTF-8\");
            post.setEntity(param);
            //执行请求
            resp = this.httpClient.execute(post);
            if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式:
                result = JSONObject.toJSONString(EntityUtils.toString(resp.getEntity()));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return new HttpResult(resp.getStatusLine().getStatusCode(),result);
    }

参数为Map的请求(JSON)

public HttpResult doPost(String url, Map<String,Object> map,String reqHeader) throws Exception {
        // 声明httpPost请求
        HttpPost post = new HttpPost(url);
        // 加入配置信息
        post.setConfig(config);
        post.setHeader(\"User-Agent\", reqHeader);
        String result = null;
        HttpResponse resp = null;
        try {
            //设置参数
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            Iterator iterator = map.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String,String> elem = (Map.Entry<String, String>) iterator.next();
                list.add(new BasicNameValuePair(elem.getKey(),String.valueOf(elem.getValue())));
            }
            if(list.size() > 0){
            	//将集合封装成UrlEncodedFormEntity设置字符格式
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,\"UTF-8\");
                post.setEntity(entity);
            }
            //执行请求
            resp = this.httpClient.execute(post);
            if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式:
                result = JSONObject.toJSONString(EntityUtils.toString(resp.getEntity()));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return new HttpResult(resp.getStatusLine().getStatusCode(),result);
    }

上传文件

public HttpResult doPostForm(String url, MultipartFile file, Map<String,Object> map,String reqHeader) throws Exception {
        // 声明httpPost请求
        HttpPost post = new HttpPost(url);
        // 加入配置信息
        post.setConfig(config);
        post.setHeader(\"User-Agent\",reqHeader );
        String result = null;
        HttpResponse resp = null;
        try {
            MultipartEntityBuilder builder =  MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE).setCharset(Consts.UTF_8);
            //要上传的文件,以文件流的形式进行传输
            builder.addBinaryBody(\"file\",file.getInputStream(), ContentType.MULTIPART_FORM_DATA, file.getOriginalFilename());
            //content-type
            ContentType strContent=ContentType.create(\"text/plain\", Charset.forName(\"UTF-8\"));
            Iterator iterator = map.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String,String> elem = (Map.Entry<String, String>) iterator.next();
                builder.addTextBody(elem.getKey(), elem.getValue(),strContent);
            }
            HttpEntity entity = builder.build();
            post.setEntity(entity);
            //执行请求
            resp = this.httpClient.execute(post);
            if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式:
                result = JSONObject.toJSONString(EntityUtils.toString(resp.getEntity()));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return new HttpResult(resp.getStatusLine().getStatusCode(),result);
    }

那么说到这里问题也差不多解决了,以上就是本人使用httpClient的简单经历,让我们一起沉浸在bug的海洋里,无法自拔吧~
PS:如有错误或者不正确的地方还请多多指教,一起共同学习共同进步

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号