Java通過HttpClient的請求封裝
阿新 • • 發佈:2019-02-14
背景
昨天在公司做專案的時候要在Java程式碼裡面呼叫網管系統的Restful介面返回Json資料,然後簡單的看了一下關於Java中發起Http或者Https請求的幾種方式,總結一下。
方法
目前JAVA實現HTTP請求的方法用的最多的有兩種:一種是通過HTTPClient這種第三方的開源框架去實現。HTTPClient對HTTP的封裝性比較不錯,通過它基本上能夠滿足我們大部分的需求,HttpClient3.1 是 org.apache.commons.httpclient下操作遠端 url的工具包,雖然已不再更新,但實現工作中使用httpClient3.1的程式碼還是很多,HttpClient4.5是org.apache.http.client下操作遠端 url的工具包,最新的;另一種則是通過HttpURLConnection去實現,HttpURLConnection是JAVA的標準類,是JAVA比較原生的一種實現方式。
我採用的是org.apache.http.client這個包來做Http請求。然後最開始分別實現了Get,Post,Put,Delete增刪改查四種請求方式,後來覺得不妥改成了一個通用的方法。
public synchronized String getCall(String url, String contentType,
Map<String, String> addRequestHeader)
throws NbiException {
log.debug("Get Rest URL = " + url);
HttpGet getRequest = new HttpGet(url);
if (!StringUtils.isEmpty(contentType)) {
getRequest.addHeader("Accept", contentType);
}
return call(addRequestHeader, getRequest);
}
public synchronized String postCall(String url, String inputParam,
String contentType, Map<String, String> addRequestHeader)
throws NbiException {
log.debug("Post Rest URL = " + url);
HttpPost postRequest = new HttpPost(url);
StringEntity input = null;
try {
if(!StringUtils.isEmpty(inputParam)){
input = new StringEntity(inputParam);
input.setContentType(contentType);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
postRequest.setEntity(input);
return call(addRequestHeader, postRequest);
}
public synchronized String deleteCall(String url) throws NbiException {
log.debug("Delete Rest URL = " + url);
HttpDelete deleteRequest = new HttpDelete(url);
return call(null, deleteRequest);
}
public synchronized String putCall(String url, String inputParam,
String contentType, Map<String, String> addRequestHeader)
throws NbiException {
log.debug("Put Rest URL = " + url);
HttpPut httpPut = new HttpPut(url);
StringEntity input = null;
try {
if(StringUtils.isNotEmpty(inputParam)){
input = new StringEntity(inputParam);
input.setContentType(contentType);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
httpPut.setEntity(input);
return call(addRequestHeader, httpPut);
}
/**
* @Author: xingrui
* @Description: support: get, post, put, delete
* @Date: 15:42 2018/6/22
*/
public String call(Map<String, String> addRequestHeader,
HttpRequestBase request) throws NbiException {
StringBuilder sb = new StringBuilder();
try {
if (addRequestHeader != null){
for (String paramKey : addRequestHeader.keySet()) {
String paramValue = addRequestHeader.get(paramKey);
request.setHeader(paramKey, paramValue);
}
}
HttpResponse response = this.execute(request);
checkHttpStatus(response);
BufferedReader br = new BufferedReader(new InputStreamReader(
(response.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null) {
sb.append(output + "\n");
}
return sb.toString();
} catch (Exception e) {
log.error(e);
throw ExceptionConverter.convertToInternalException(e);
}
}
具體的呼叫
public synchronized boolean login()
throws NbiException {
String url = "https://localhost/xxx/xxx";
String username = "xxxx";
String password = "xxxx";
log.debug("Get Token Url: " + url);
String originalCredentials = username + ":" + password;
String base64Credentials = new String(Base64
.encodeBase64(originalCredentials.getBytes()));
RestfulConstant.BASIC_TOKEN = "Basic " + base64Credentials;
String inputParams = "{\"grant_type\":\"client_credentials\"}";
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", RestfulConstant.BASIC_TOKEN);
headers.put("Content-Type", "application/json");
String out = postCall(url, inputParams,
"application/json", headers);
JsonNode jsonNode = JsonUtil.toNode(out);
RestfulConstant.ACCESS_TOKEN = jsonNode.get("access_token").asText();
RestfulConstant.REFRESH_TOKEN = jsonNode.get("refresh_token").asText();
return true;
}
根據實際需要自由更改程式碼即可。
發起Https請求
Https就是在Http的基礎上使用了SSLSocket安全套接字的請求,使用SSL或TLS協議的安全套接字。
如果伺服器中沒有相關連結的SSL證書,就不能信任此連結,訪問不到。所以我們要在請求之前加一個信任管理器,去實現X509TrustManager 這個類。
public static void main(String[] args) throws Exception {
X509TrustManager x509m = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
};
// 獲取一個SSLContext例項
SSLContext s = SSLContext.getInstance("SSL");
// 初始化SSLContext例項
s.init(null, new TrustManager[] { x509m },
new java.security.SecureRandom());
// 列印這個SSLContext例項使用的協議
System.out.println("預設安全套接字使用的協議: " + s.getProtocol());
// 獲取SSLContext例項相關的SSLEngine
SSLEngine e = s.createSSLEngine();
System.out
.println("支援的協議: " + Arrays.asList(e.getSupportedProtocols()));
System.out.println("啟用的協議: " + Arrays.asList(e.getEnabledProtocols()));
System.out.println("支援的加密套件: "
+ Arrays.asList(e.getSupportedCipherSuites()));
System.out.println("啟用的加密套件: "
+ Arrays.asList(e.getEnabledCipherSuites()));
}
然後就可以愉快的發起Https請求了。