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请求了。

参考文章

https://www.cnblogs.com/hhhshct/p/8523697.html Java实现Http请求的三种方式

https://blog.csdn.net/guozili1/article/details/53995121 如何在java中发起http和https请求

[https://blog.csdn.net/qq_31694651/article/details/52372341](java SSLSocket的详解) java SSLSocket的详解

猜你喜欢

转载自blog.csdn.net/fututadeyoushang/article/details/80941560