spring-boot集成httpClient实现基本的远程调用

本文参考博客地址为:https://blog.csdn.net/justry_deng/article/details/81042379  

建议先看上面那位老哥的博客再看此文。(上面那篇写的非常详细,我也是根据他的博客完成的,然后又加以优化)

闲话少说直接上代码:

引入相关依赖:(本文会用到这三条)

<!--httpclient引入-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.9</version>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <!-- 支持 @ConfigurationProperties 注解 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

创建HttpClientUtil工具类,代码如下:

package com.test.demo;

import com.alibaba.fastjson.JSON;
import com.test.demo.model.User;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

/**
 * ClassName:    HttpClientTest
 * Package:    com.test.demo
 * Description: httpClient方法封装
 * Datetime:    2020/1/13   10:45
 * Author:   zhoukaishun
 */
@Component
public class HttpClientUtil {

    @Autowired
    private HttpClientConfigure httpClientConfigure;

   /**
    * @description GET封装
    * @author zhoukaishun
    * @date 2020/1/13 13:12
    */
    public  void doGetHttp(List<NameValuePair> params,Boolean haveParams) {
        // 获得Http客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 参数
        URI uri = null;
        try {
            // 设置uri信息,并将参数集合放入uri;
            if(haveParams){//有参调用
                uri = new URIBuilder().setScheme(httpClientConfigure.getScheme()).setHost(httpClientConfigure.getHost())
                        .setPort(httpClientConfigure.getPort()).setPath(httpClientConfigure.getMapPath().get("interface2"))
                        .setParameters(params).build();
            }else{//无参调用
                uri = new URIBuilder().setScheme(httpClientConfigure.getScheme()).setHost(httpClientConfigure.getHost())
                        .setPort(httpClientConfigure.getPort()).setPath(httpClientConfigure.getMapPath().get("interface1"))
                        .build();
            }
        } catch (URISyntaxException e1) {
            e1.printStackTrace();
        }
        // 创建Get请求
        HttpGet httpGet = new HttpGet(uri);
        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 配置信息
            RequestConfig requestConfig = RequestConfig.custom()
                    // 设置连接超时时间(单位毫秒)
                    .setConnectTimeout(5000)
                    // 设置请求超时时间(单位毫秒)
                    .setConnectionRequestTimeout(5000)
                    // socket读写超时时间(单位毫秒)
                    .setSocketTimeout(5000)
                    // 设置是否允许重定向(默认为true)
                    .setRedirectsEnabled(true).build();

            // 将上面的配置信息 运用到这个Get请求里
            httpGet.setConfig(requestConfig);
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * @description POST封装
     * @author zhoukaishun
     * @date 2020/1/13 14:01
     */
    public  void doPostHttp(User user,Boolean haveParam) {
        // 获得Http客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        URI uri = null;
        try {
            // 设置uri信息,并将参数集合放入uri;
            uri = new URIBuilder().setScheme(httpClientConfigure.getScheme()).setHost(httpClientConfigure.getHost())
                    .setPort(httpClientConfigure.getPort())
                    .setPath(haveParam?httpClientConfigure.getMapPath().get("interface4"):httpClientConfigure.getMapPath().get("interface3"))
                    .build();
        } catch (URISyntaxException e1) {
            e1.printStackTrace();
        }
        // 创建Post请求
        HttpPost httpPost = new HttpPost(uri);
        if(haveParam){
            //入参
            // 利用阿里的fastjson,将Object转换为json字符串;
            // (需要导入com.alibaba.fastjson.JSON包)
            String jsonString = JSON.toJSONString(user);

            StringEntity entity = new StringEntity(jsonString, "UTF-8");
            // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
            httpPost.setEntity(entity);

            httpPost.setHeader("Content-Type", "application/json;charset=utf8");
        }
        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}

其中大部分代码基本不变,只有对url的拼接做了一些处理,可以看到我们注入了一个HttpClientConfigure实例,因为我们需要访问的路径情况有很多种,但是我们不可能每次都去改util下的url拼接代码,所以引入一个HttpClientConfigure,这是我自定义的一个类,用于存储我们拼接url可能遇到的情况。代码如下:

package com.test.demo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * ClassName:    HttpClientConfigure
 * Package:    com.test.demo
 * Description: 接收配置信息
 * Datetime:    2020/1/13   14:41
 * Author:   zhoukaishun
 */
@Component
@ConfigurationProperties(prefix="httpclientconfigure")
@Data
public class HttpClientConfigure {

    private Map<String, String> mapPath = new HashMap<>();

    private String scheme;

    private String host;

    private Integer port;

}

其中的@ConfigurationProperties注解 前面提到过,在pom中,其中属性值配置在yml文件中,如下(具体内容根据自己的需求来定):

到这里就可以开始测试了,可以在本地启动两个服务(一个服务也行),根据自己controller里面的访问路径配置httpclientconfigure,然后直接调用自己controller里方法即可。

以我的demo为例,调用者controller代码如下:


    @GetMapping
    @RequestMapping("/doGetHaveNoParam")
    public void doGetHaveNoParam(){
        httpClientUtil.doGetHttp(null,false);
    }

    @GetMapping
    @RequestMapping("/doGetHaveParam")
    public void doGetHaveParam(){
        System.out.println("调用有参Get请求,当前时间:"+System.currentTimeMillis());
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("name", "&"));
        params.add(new BasicNameValuePair("age", "22"));
        httpClientUtil.doGetHttp(params,true);
    }
    @PostMapping
    @RequestMapping("/doPostHaveNoParam")
    public void doPostHaveNoParam(){
        httpClientUtil.doPostHttp(null,false);
    }

    @PostMapping
    @RequestMapping("/doPostHaveParam")
    public void doPostHaveParam(){
        httpClientUtil.doPostHttp(new User("name",11),true);
    }

被调用者controller代码如下:

    @RequestMapping("/doGetHaveNoParam")
    public String doGetHaveNoParam(){
        return "doGetHaveNoParam successful";
    }

    @RequestMapping("/doGetHaveParam")
    public List<User> doGetHaveParam(String name,Integer age){
        return getUserByAge(name,age);
    }

    @PostMapping
    @RequestMapping("/doPostHaveNoParam")
    public String doPostHaveNoParam(){
        return "doPostHaveNoParam successful";
    }

    @PostMapping
    @RequestMapping("/doPostHaveParam")
    public String doHttpPostParam(@RequestBody User user){
        return "do Post params:name="+user.getName()+",age="+user.getAge();

使用postman测试如下:

请求路径分别为:

http://localhost:8081/user/doGetHaveNoParam

http://localhost:8081/user/doGetHaveParam

http://localhost:8081/user/doPostHaveNoParam

http://localhost:8081/user/doPostHaveParam

响应结果如下:

至此结束,如若对你有帮助点个赞呗。

发布了20 篇原创文章 · 获赞 58 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/zks_4826/article/details/103959774