package com.example.demo.utils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
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.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 提供調用第三方API 的 get與 post 接口
* Created by baizhuang on 2019/9/12 11:37.
*/
@Slf4j
public class HttpClient {
/**
* 表單格式傳輸
*/
private static final String FORM_CONTEXT_TYPE ="application/x-www-form-urlencoded";
/**
* json 默認的編碼類型
*/
private static final String JSON_CONTENT_TYPE = "application/json";
/**
* 默認的編碼格式
*/
private static final String DEFAULT_CHARSET = "UTF-8";
/**
* 請求配置對象
*/
private static RequestConfig requestConfig;
/**
* get 請求,將參數包含在 url 路徑中
* url : 路徑
* return: json 對象
*/
public static JSONObject doGet(String url){
JSONObject jsonObject = null;
try(CloseableHttpClient client = HttpClients.createDefault();){
HttpGet request = new HttpGet(url);
request.setConfig(requestConfig);
try(CloseableHttpResponse response = client.execute(request);){
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == HttpStatus.SC_OK){
HttpEntity entity = response.getEntity();
String responseContent = EntityUtils.toString(entity);
jsonObject = JSONObject.parseObject(responseContent);
}else{
log.info("Get請求失敗:{},狀態碼:{}",url,statusCode);
}
}
}catch (IOException e){
log.info("Get 請求異常:{},狀態碼:{}",url,e.getMessage());
e.printStackTrace();
}
return jsonObject;
}
/**
* get 請求,將參數以Map 的形式傳入
* path : 包括 協議、主機、端口、資源路徑
* param: 請求參數
*
* @param
*/
public static JSONObject doGet(String path,Map<String,String> params){
List<NameValuePair> queryParans = convertParamsMapToList(params);
URI uri = null;
try{
uri = new URIBuilder()
.setPath(path)
.setParameters(queryParans)
.build();
}catch (URISyntaxException e){
e.printStackTrace();
}
return doGet(uri.toString());
}
/**
* 將Map<String,String> 類型的請求參數轉換為 List<NameValuePair>
* @param
*
*/
private static List<NameValuePair> convertParamsMapToList(Map<String,String> params){
List<NameValuePair> queryParams = new ArrayList<>();
for(String s : params.keySet()){
queryParams.add(new BasicNameValuePair(s,params.get(s)));
}
return queryParams;
}
/**
* 將請求拆分開傳入
*
* scheme 請求協議
* host 主機地址
* port 端口
* path 路徑
* params 請求參數
* @param
*/
public static JSONObject doGet(String scheme,String host,Integer port,String path,Map<String,String> params){
List<NameValuePair> queryParams = convertParamsMapToList(params);
URI uri = null;
try {
uri = new URIBuilder().setScheme(scheme)
.setHost(host)
.setPort(port)
.setPath(path)
.setParameters(queryParams)
.build();
}catch (URISyntaxException e){
e.printStackTrace();
}
return doGet(uri.toString());
}
/**
* post 請求,請求參數被封裝在 JSONObject
* url : 請求地址
* jsonParam :請求參數
*
*/
public static JSONObject doPost(String url,JSONObject jsonParam){
return doPost(url,jsonParam,null);
}
/**
* doPost ,以表單提交
*/
public static JSONObject doPost(String url,String params){
return doPost(url,params,FORM_CONTEXT_TYPE,null);
}
/**
* post 請求,請求參數被封裝在 JSONObject 中,可以設置字符編碼
* url: 請求地址
* jsonParam : 請求參數
* charset 字符編碼方法
*/
public static JSONObject doPost(String url,JSONObject jsonParam,String charset){
return doPost(url,jsonParam.toJSONString(),JSON_CONTENT_TYPE,charset);
}
public static JSONObject doPost(String url,JSONObject jsonParam,boolean isJsonParam,String charset){
return doPost(url,jsonParam.toJSONString(),JSON_CONTENT_TYPE,charset);
}
/**
* post 請求,參數為字符串,可以為 JSON ,可以為普通格式,可以設置字符編碼
* 如果為 json 格式, isJsonStringParam = true
* 如果是普通格式: name =Jack&age =10 ,則 isJsonStringParam = false
*
* url : 請求地址
* stringParam 請求參數字符串
* isJsonStringParam : 請求是否為 json 格式
* charset 字符編碼格式
*/
public static JSONObject doPost(String url,String stringParam,boolean isJsonStringParam,String charset){
JSONObject jsonResult = null;
if(isJsonStringParam){
jsonResult = doPost(url,stringParam,JSON_CONTENT_TYPE,charset);
}else{
jsonResult = doPost(url,stringParam,FORM_CONTEXT_TYPE,charset);
}
return jsonResult;
}
/**
* Post 請求
* url: 請求地址
* requestParam 請求參數,字符串格式
* contentType 內容編碼格式
* charset 字符編碼格式
*
*/
public static JSONObject doPost(String url,String requestParam,String contentType,String charset){
charset = charset==null?DEFAULT_CHARSET:charset;
JSONObject jsonResult = null;
try(CloseableHttpClient httpClient = HttpClients.createDefault();){
HttpPost httpPost = new HttpPost(url);
//構造實體請求
StringEntity requestEntity = new StringEntity(requestParam,charset);
requestEntity.setContentEncoding(charset);
requestEntity.setContentType(contentType);
httpPost.setEntity(requestEntity);
httpPost.setConfig(requestConfig);
try(CloseableHttpResponse response = httpClient.execute(httpPost);){
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == HttpStatus.SC_OK){
HttpEntity responseEntity = response.getEntity();
String responseContent = EntityUtils.toString(responseEntity,charset);
jsonResult = JSONObject.parseObject(responseContent);
}else{
log.error("post 請求失敗:{},狀態碼:{}",url,statusCode);
}
}
}catch (IOException e){
e.printStackTrace();
}
return jsonResult;
}
}