1. 程式人生 > >Java通過HttpClient的請求封裝

Java通過HttpClient的請求封裝

背景

昨天在公司做專案的時候要在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請求了。

參考文章