0
点赞
收藏
分享

微信扫一扫

springboot 整合httpclient【面试+工作】


1.首先加入httpclient需要的jar包

<dependency>

    <groupId>org.apache.httpcomponents</groupId>

    <artifactId>httpclient</artifactId>

    <version>4.3.1</version>

</dependency>


2.在配置文件中加入httpclient需要的一些配置参数

#最大连接数

http.maxTotal = 100

#并发数

http.defaultMaxPerRoute = 20

#创建连接的最长时间

http.connectTimeout=1000

#从连接池中获取到连接的最长时间

http.connectionRequestTimeout=500

#数据传输的最长时间

http.socketTimeout=10000

#提交请求前测试连接是否可用

http.staleConnectionCheckEnabled=true


3.注入连接池等,用于在service层获取httpclient

@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();

    }

}


4.编写一个案例Controller层

@RestController

public class HttpClientController {

    @Resource

    private HttpAPIService httpAPIService;

    @RequestMapping("httpclient")

    public String test() throws Exception {

        String str = httpAPIService.doGet("http://www.baidu.com");

        System.out.println(str);

        return "hello";

    }

}


5.service层

@Service

public class HttpAPIService {

    @Autowired

    private CloseableHttpClient httpClient;


    @Autowired

    private RequestConfig config;


    /**

     * 不带参数的get请求,如果状态码为200,则返回body,如果不为200,则返回null

     * 

     * @param url

     * @return

     * @throws Exception

     */

    public String doGet(String url) throws Exception {

        // 声明 http get 请求

        HttpGet httpGet = new HttpGet(url);


        // 装载配置信息

        httpGet.setConfig(config);


        // 发起请求

        CloseableHttpResponse response = this.httpClient.execute(httpGet);


        // 判断状态码是否为200

        if (response.getStatusLine().getStatusCode() == 200) {

            // 返回响应体的内容

            return EntityUtils.toString(response.getEntity(), "UTF-8");

        }

        return null;

    }


    /**

     * 带参数的get请求,如果状态码为200,则返回body,如果不为200,则返回null

     * 

     * @param url

     * @return

     * @throws Exception

     */

    public String doGet(String url, Map<String, Object> map) throws Exception {

        URIBuilder uriBuilder = new URIBuilder(url);


        if (map != null) {

            // 遍历map,拼接请求参数

            for (Map.Entry<String, Object> entry : map.entrySet()) {

                uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());

            }

        }


        // 调用不带参数的get请求

        return this.doGet(uriBuilder.build().toString());

    }


    /**

     * 带参数的post请求

     * 

     * @param url

     * @param map

     * @return

     * @throws Exception

     */

    public HttpResult doPost(String url, Map<String, Object> map) throws Exception {

        // 声明httpPost请求

        HttpPost httpPost = new HttpPost(url);

        // 加入配置信息

        httpPost.setConfig(config);


        // 判断map是否为空,不为空则进行遍历,封装from表单对象

        if (map != null) {

            List<NameValuePair> list = new ArrayList<NameValuePair>();

            for (Map.Entry<String, Object> entry : map.entrySet()) {

                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));

            }

            // 构造from表单对象

            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8");


            // 把表单放到post里

            httpPost.setEntity(urlEncodedFormEntity);

        }


        // 发起请求

        CloseableHttpResponse response = this.httpClient.execute(httpPost);

        return new HttpResult(response.getStatusLine().getStatusCode(), EntityUtils.toString(

                response.getEntity(), "UTF-8"));

    }


    /**

     * 不带参数post请求

     * 

     * @param url

     * @return

     * @throws Exception

     */

    public HttpResult doPost(String url) throws Exception {

        return this.doPost(url, null);

    }

}


6.处理关闭连接的线程

@Componentpublic 

class IdleConnectionEvictor extends Thread {

@Autowiredprivate 

HttpClientConnectionManager connMgr;

private volatile boolean shutdown;

public IdleConnectionEvictor() {

super();

super.start();

}

@Override

public void run() {

try {

while (!shutdown) {

synchronized (this) {

wait(5000);

// 关闭失效的连接

connMgr.closeExpiredConnections();

}

}

catch (InterruptedException ex) {

// 结束

}

}

//关闭清理无效连接的线程

public void shutdown() {

shutdown = true;synchronized (this) {

notifyAll();

}

}

}


7.自定义返回结果类型

public class HttpResult {


// 响应的状态码

private int code;


// 响应的响应体 

private String body;


get/set…

}


springboot 整合httpclient【面试+工作】_实例化

springboot 整合httpclient【面试+工作】_实例化_02springboot 整合httpclient【面试+工作】_连接池_03springboot 整合httpclient【面试+工作】_连接池_04springboot 整合httpclient【面试+工作】_连接池_05



举报

相关推荐

0 条评论