SpringBoot使用HttpClient远程调用

HttpClient入门案例

1.引入依赖

<!-- http所需包 -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
</dependency>
<!-- /http所需包 -->

<!-- 数据解析所需包 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.4</version>
</dependency>
<!-- /数据解析所需包 -->

2.发送GET请求

步骤如下:

​ 1创建一个客户端 CloseableHttpClient

​ 2创建一个get方法请求实例 HttpGet

​ 3发送请求 execute

​ 4获取响应的头信息

​ 5获取响应的主题内容

​ 6关闭响应对象

public class DoGET {

    public static void main(String[] args) throws Exception {
        // 创建Httpclient对象,相当于打开了浏览器
        CloseableHttpClient httpclient = HttpClients.createDefault();

        // 创建HttpGet请求,相当于在浏览器输入地址
        HttpGet httpGet = new HttpGet("http://www.baidu.com/");

        CloseableHttpResponse response = null;
        try {
            // 执行请求,相当于敲完地址后按下回车。获取响应
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                // 解析响应,获取数据
                String content = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println(content);
            }
        } finally {
            if (response != null) {
                // 关闭资源
                response.close();
            }
            // 关闭浏览器
            httpclient.close();
        }

    }
}

3.发送带参数的GET请求

1创建一个客户端 CloseableHttpClient

2 通过URIBuilder传递参数

3创建一个get方法请求实例 HttpGet

4发送请求 execute

5获取响应的头信息

6获取响应的主题内容

7关闭响应对象

访问网站的爬虫协议:https:// www.baidu.com/robots.txt

public class DoGETParam {

   public static void main(String[] args) throws Exception {
       // 创建Httpclient对象
       CloseableHttpClient httpclient = HttpClients.createDefault();
       // 创建URI对象,并且设置请求参数
       URI uri = new URIBuilder("http://www.baidu.com/s").setParameter("wd", "java").build();
       // 创建http GET请求
       HttpGet httpGet = new HttpGet(uri);

       CloseableHttpResponse response = null;
       try {
           // 执行请求
           response = httpclient.execute(httpGet);
           // 判断返回状态是否为200
           if (response.getStatusLine().getStatusCode() == 200) {
               // 解析响应数据
               String content = EntityUtils.toString(response.getEntity(), "UTF-8");
               System.out.println(content);
           }
       } finally {
           if (response != null) {
               response.close();
           }
           httpclient.close();
       }
   }
}

4.发送POST请求

/*
* 演示:使用HttpClient发起POST请求
*/
public class DoPOST {
   public static void main(String[] args) throws Exception {
       // 创建Httpclient对象
       CloseableHttpClient httpclient = HttpClients.createDefault();
       // 创建http POST请求
       HttpPost httpPost = new HttpPost("http://www.oschina.net/");
       // 把自己伪装成浏览器。否则开源中国会拦截访问
       httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");

       CloseableHttpResponse response = null;
       try {
           // 执行请求
           response = httpclient.execute(httpPost);
           // 判断返回状态是否为200
           if (response.getStatusLine().getStatusCode() == 200) {
               // 解析响应数据
               String content = EntityUtils.toString(response.getEntity(), "UTF-8");
               System.out.println(content);
           }
       } finally {
           if (response != null) {
               response.close();
           }
           // 关闭浏览器
           httpclient.close();
       }

   }
}

4.发送带参数POST请求

/*
* 演示:使用HttpClient发起带有参数的POST请求
*/
public class DoPOSTParam {

   public static void main(String[] args) throws Exception {
       // 创建Httpclient对象
       CloseableHttpClient httpclient = HttpClients.createDefault();
       // 创建http POST请求,访问开源中国
       HttpPost httpPost = new HttpPost("http://www.oschina.net/search");

       // 根据开源中国的请求需要,设置post请求参数
       List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
       parameters.add(new BasicNameValuePair("scope", "project"));
       parameters.add(new BasicNameValuePair("q", "java"));
       parameters.add(new BasicNameValuePair("fromerr", "8bDnUWwC"));
       // 构造一个form表单式的实体
       UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
       // 将请求实体设置到httpPost对象中
       httpPost.setEntity(formEntity);

       CloseableHttpResponse response = null;
       try {
           // 执行请求
           response = httpclient.execute(httpPost);
           // 判断返回状态是否为200
           if (response.getStatusLine().getStatusCode() == 200) {
               // 解析响应体
               String content = EntityUtils.toString(response.getEntity(), "UTF-8");
               System.out.println(content);
           }
       } finally {
           if (response != null) {
               response.close();
           }
           // 关闭浏览器
           httpclient.close();
       }
   }
}

同步驱动系统

1.引入依赖

<!-- http所需包 -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
</dependency>
<!-- /http所需包 -->

<!-- 数据解析所需包 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.4</version>
</dependency>
<!-- /数据解析所需包 -->

2. 增加一个配置类去读取外部http配置

新增HttpProperties配置类来获取外部properties中的参数信息

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import lombok.Data;

@Configuration
@ConfigurationProperties(prefix = "http")
@PropertySource(value = "classpath:httpConfig.properties", encoding = "UTF-8")
@Component("http")
@Primary
@Data
public class HttpProperties {
    private String ip;
    
    private int port;
    
    private String customerName;
    
    private String addStations;
    
    private String addDevice;
    
    private String addDatas;
    
    private String transferNoLists;



}

properties中的参数信息:

http.ip = 127.0.0.1
http.port = 12580
http.customerName = /save
http.addStations = /datas
http.addDevice = /datas
http.addDatas = /datas
#需要转发的仪表编号(大客户的FlowMeterNo)
http.transferNoLists = ["AT51901500118","NO1002"]

3.自定义一个httpclient类

httpclient类由两个方法:一个dopost方法,一个doPostFormUrlEncodedFormEntity方法,可以根据自己的场景需求增加需求

package com.diyuan.sync.http;

import java.util.Map;

public class HttpClient {
    public static String doPost(String host, String path, Map<String, String> querys, Map<String, String> headers, String contentMap) {
        CommandHttp client = new CommandHttp();
        String response = client.doPost(host, path, querys, headers, contentMap);
        client.close();
        return response;
    };
    public static String doPostFormUrlEncodedFormEntity(String host, String path, Map<String, String> querys, Map<String, String> headers, Map<String, String> formContent) {
        CommandHttp client = new CommandHttp();
        String response = client.doPostFormUrlEncodedFormEntity(host, path, querys, headers, formContent);
        client.close();
        return response;
    }


}

4.创建一个commandhttp类

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.diyuan.sync.util.CustomLogUtil;


public class CommandHttp {
    private final static Logger logger =  LogManager.getLogger();
    private CloseableHttpClient httpClient;
    private RequestConfig requestConfig;
    
    public CommandHttp() {//http请求设置
        this.httpClient = HttpClients.createDefault();
        this.requestConfig = RequestConfig.custom()
                   .setConnectTimeout(2000)
                   .setConnectionRequestTimeout(1000)
                   .setSocketTimeout(2000)
                   .build();
    }
    public void init() {
        this.httpClient = HttpClients.createDefault();
        this.requestConfig = RequestConfig.custom()
                   .setConnectTimeout(2000)
                   .setConnectionRequestTimeout(1000)
                   .setSocketTimeout(2000)
                   .build();
    }
    public void close() {
        if(httpClient != null) {
            try {
               httpClient.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
        }
    }
    //doPost 有返回 applicationo/json
    public String doPost(String host, String path, Map<String, String> querys, Map<String, String> headers, String contentMap) {
        HttpPost httpPost = null;
        try {
           httpPost = new HttpPost(buildUrl(host, path, querys));//利用buildUrl()方法把httpproperties中的信息连成URI
       } catch (UnsupportedEncodingException e) {
           e.printStackTrace();
       }
        httpPost.setConfig(requestConfig);
        //添加请求头
        if(headers != null) {//设置请求头信息
            for (Map.Entry<String, String> entry : headers.entrySet()) {
               httpPost.addHeader(entry.getKey(), entry.getValue());
           }
        }
        String result = "";
        try {
        if(StringUtils.isNotBlank(contentMap)) {
            StringEntity entity = new StringEntity(contentMap, StandardCharsets.UTF_8);
            httpPost.setEntity(entity);
        }
        //执行返回结果
        CloseableHttpResponse response = httpClient.execute(httpPost);
        if(response != null && response.getStatusLine().getStatusCode() == 200) {
               HttpEntity entity = response.getEntity();
               result = EntityUtils.toString(entity);
       }else {
           logger.log(CustomLogUtil.BUSINESS, response.getStatusLine().getStatusCode());
           logger.log(CustomLogUtil.BUSINESS, response.getStatusLine().getReasonPhrase());
           return "fail";
           }
        }catch(Exception e) {
            result = "fail";
            e.printStackTrace();
        }finally {
            httpPost.abort();
        }
        return result;
    }
   //doPost请求  application/x-www-form-urlencoded
    public String doPostFormUrlEncodedFormEntity(String host, String path, Map<String, String> querys, Map<String, String> headers, Map<String, String> formContent) {
        HttpPost httpPost = null;
        try {
           httpPost = new HttpPost(this.buildUrl(host, path, querys));
       } catch (UnsupportedEncodingException e) {
           e.printStackTrace();
       }
        httpPost.setConfig(requestConfig);
        //添加请求头
        if(headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
               httpPost.addHeader(entry.getKey(), entry.getValue());
           }
        }
        //设置body
        List<NameValuePair> pairs = new ArrayList<>();
        if(formContent != null) {
            for (Map.Entry<String, String> entry : formContent.entrySet()) {
               pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
           }
        }
        String result = "";
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(pairs, "utf-8"));
            logger.log(CustomLogUtil.BUSINESS, httpPost.toString());
            //执行返回结果
            CloseableHttpResponse response = httpClient.execute(httpPost);
            if(response != null && response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity);
                logger.info("http请求响应:" + response);;
            }else {
                logger.info("http请求响应:" + response);;
            }
        }catch(Exception e) {
            result = "fail";
            e.printStackTrace();
        }finally {
            httpPost.abort();
        }
        return result;
    }
    private String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append("http://");
        if(!StringUtils.isBlank(host)) {
            sbUrl.append(host);
        }
        if(!StringUtils.isBlank(path)) {
            sbUrl.append(path);
        }
        if(querys != null) {
            StringBuilder sbQuery = new StringBuilder();
            for(Map.Entry<String, String> query : querys.entrySet()) {
                if(sbQuery.length() > 0) {
                    sbQuery.append("&");
                }
                if(StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
                    sbQuery.append(query.getValue());
                }
                if(!StringUtils.isBlank(query.getKey())) {
                    sbQuery.append(query.getKey());
                    if(!StringUtils.isBlank(query.getValue())) {
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
                    }
                }
            }
            if(sbQuery.length() > 0) {
                sbUrl.append("?").append(sbQuery);
            }
        }
        return sbUrl.toString();
    }
    
    //添加头部信息
    private Map<String, String> getHttpHeaders() {
            Map<String, String> map = new HashMap<>();
            map.put("Accept", "application/json");
            map.put("Content-Type", "application/json");
            map.put("panda-token", tokenBean.getToken());
        return map;
    }


}

5.编写httpservice类来完成具体业务场景下的http发送任务

service接口

package com.diyuan.sync.service;

import java.util.List;
import java.util.Map;

import com.diyuan.sync.form.HistoryForm;
import com.diyuan.sync.form.StationForm;

public interface HttpService {

	/**
	 * 
	 * @return
	 * @explains 发送历史数据
	 */
	public String sendHistorys(List<HistoryForm> historys, String stationNo);

}

service实现类

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.transaction.Transactional;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.diyuan.sync.config.HttpProperties;
import com.diyuan.sync.form.HistoryForm;
import com.diyuan.sync.form.StationForm;
import com.diyuan.sync.form.customer.OutputHistoryForm;
import com.diyuan.sync.form.customer.OutputStationForm;
import com.diyuan.sync.http.HttpClient;
import com.diyuan.sync.service.HttpService;
import com.diyuan.sync.util.CustomLogUtil;
@Service("httpService")
@Transactional
public class HttpServiceImpl implements HttpService{
	private static final Logger log = LogManager.getLogger();
	
	@Autowired
	private HttpProperties httpProperties;//获取转发URI配置


	@Override
	public String sendHistorys(List<HistoryForm> historys,String stationNo) {
		List<OutputHistoryForm> lists = historys.stream().map(d -> new OutputHistoryForm(d, stationNo)).collect(Collectors.toList());
		log.log(CustomLogUtil.BUSINESS, "转发历史数据:" + JSON.toJSONString(lists, SerializerFeature.WriteMapNullValue));
		String response = HttpClient.doPost(httpProperties.getIp() + ":" + httpProperties.getPort(),
				httpProperties.getCustomerName() + httpProperties.getAddDatas(), null,
				getHttpHeaders(), JSON.toJSONString(lists, SerializerFeature.WriteMapNullValue));
		if("fail".equals(response)) {
			log.log(CustomLogUtil.BUSINESS, "发送历史数据失败" + response);
			return "fail";
		}
		return response;
	}

	private Map<String, String> getHttpHeaders(){
		Map<String, String> map = new HashMap<>();
		map.put("Accept", "application/json");
		map.put("Content-Type", "application/json");
	return map;

	}

}