同步、异步httpclient

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/denialLiu/article/details/79187407

同步httpclient

当客户端请求数量不是非常大,请求Response RT时间在能接受范围时,这种方式更适合。

public class SyncHttpClients {
    private static Logger                             logger                = Logger.getLogger(HttpClientUtil.class);
    private final static String                       DEFAULT_CHARSETNAME   = "UTF-8";
    private final static int                          DEFAULT_TIMEOUT       = 5000;
    private static MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
    static {
        httpConnectionManager.getParams().setDefaultMaxConnectionsPerHost(3);
        httpConnectionManager.getParams().setMaxTotalConnections(30);
        httpConnectionManager.getParams().setConnectionTimeout(3000);
        httpConnectionManager.getParams().setSoTimeout(5000);
        httpConnectionManager.getParams().setTcpNoDelay(true);
        httpConnectionManager.getParams().setStaleCheckingEnabled(false);
        //这里的单位是秒
        httpConnectionManager.getParams().setLinger(1);
        ///如果发生错误则连续尝试1次
        httpConnectionManager.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(1, false));
        //处理无证书的https
        Protocol myhttps = new Protocol("https", new HTTPSSecureProtocolSocketFactory(), 443);
        Protocol.registerProtocol("https", myhttps);
    }
    /**
     * 根据url获取ResponseBody,method=get
     * @param  url exp:http://192.168.1.1/api.do
     * @param  charsetName 默认使用UTF-8编码
     * @return 以String的方式返回
     * @throws UnsupportedEncodingException
     */
    public static String getDataAsStringFromUrl(String url, String charsetName) {
        return getDataAsStringFromUrl(url, charsetName, DEFAULT_TIMEOUT);
    }
    public static String getDataAsStringFromUrl(String url) {
        return getDataAsStringFromUrl(url, null, DEFAULT_TIMEOUT);
    }
    public static String getDataAsStringFromUrl(String url, int timeout) {
        return getDataAsStringFromUrl(url, null, timeout);
    }

    /**
     * 根据url获取ResponseBody,method=get
     * @param url exp:http://192.168.1.1/api.do
     * @return 以byte[]的方式放回
     */
    private static byte[] getDataFromUrl(String url, int timeout) {
        if (StringUtils.isBlank(url)) {
            logger.error("url is blank!");
            return null;
        }
        HttpClient httpClient = new HttpClient(httpConnectionManager);

        // 连接超时
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(3000);
        // 等待数据返回超时
        httpClient.getParams().setSoTimeout(timeout);
        GetMethod method = new GetMethod(url);
        method.setFollowRedirects(false);

        try {
            int statusCode = httpClient.executeMethod(method);
            if (statusCode == HttpStatus.SC_OK) {
                return method.getResponseBody();
            } else {
                throw new RuntimeException("http request error,return code:" + statusCode + ",msg:"
                                           + new String(method.getResponseBody()));
            }
        } catch (HttpException e) {
            logger.error("url:" + url, e);
        } catch (IOException e) {
            logger.error("url:" + url, e);
        } finally {
            // Release the connection.
            method.releaseConnection();
        }
        return null;
    }

    /**
     * 探测url是否正常,返回200 ok表示正常
     * @param url
     * @return
     */
    public static boolean testUrlIsOk(String url) {
        if (StringUtils.isBlank(url)) {
            return false;
        }
        if (!SecurityUrlCheck.checkUrl(url)) {
            logger.error("url is not security!");
            return false;
        }
        HttpClient httpClient = new HttpClient();
        // 连接超时
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(1000);
        // 等待数据返回超时
        httpClient.getParams().setSoTimeout(2000);
        GetMethod method = new GetMethod(url);
        method.setFollowRedirects(false);
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));
        try {
            int statusCode = httpClient.executeMethod(method);
            if (statusCode == HttpStatus.SC_OK) {
                return true;
            }
        } catch (HttpException e) {
        } catch (IOException e) {
        } finally {
            method.releaseConnection();
        }
        return false;
    }

    public static String getDataAsStringFromUrl(String url, String charsetName, int timeout) {
        if (StringUtils.isBlank(url)) {
            logger.error("url is blank!");
            return null;
        }
        if (StringUtils.isBlank(charsetName)) {
            charsetName = DEFAULT_CHARSETNAME;
        }
        byte[] responseBody = getDataFromUrl(url, timeout);
        if (null != responseBody) {
            try {
                return new String(responseBody, charsetName);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e.getMessage());
            }
        }
        return null;
    }

    /**
     * 根据url获取ResponseBody,method=post
     */
    public static String getDataAsStringFromPostUrl(String url, Map<String, String> map) {
        return getDataAsStringFromPostUrl(url, map, DEFAULT_TIMEOUT);

    }

    public static String getDataAsStringFromPostUrl(String url, Map<String, String> map, int timeout) {
        return getDataAsStringFromPostUrl(url, map, timeout, null);
    }

    public static String getDataAsStringFromPostUrl(String url, String jsonBody, int timeout,
                                                    Map<String, Object> httpMethodParams) {
        Assert.hasText(url, "url can not be blank!");
        HttpClient httpClient = new HttpClient(httpConnectionManager);
        // 连接超时
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(3000);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout);
        // 等待数据返回超时
        httpClient.getParams().setSoTimeout(timeout);
        PostMethod method = new PostMethod(url);
        // 默认是utf8,可以用参数httpMethodParams更改
        method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, DEFAULT_CHARSETNAME);
        if (null != httpMethodParams) {
            for (Map.Entry<String, Object> entry : httpMethodParams.entrySet()) {
                method.getParams().setParameter(entry.getKey(), entry.getValue());
            }
        }
        RequestEntity se;
        try {
            se = new StringRequestEntity(jsonBody, "application/json", "UTF-8");
            method.setRequestEntity(se);
            int statusCode = httpClient.executeMethod(method);
            if (statusCode == HttpStatus.SC_OK) {
                return new String(method.getResponseBody(), DEFAULT_CHARSETNAME);
            } else {
                throw new RuntimeException("http request error,return code:" + statusCode + ",msg:"
                                           + new String(method.getResponseBody()));
            }
        } catch (HttpException e) {
            logger.error("HttpException url request error:" + url, e);
        } catch (IOException e) {
            logger.error("IOException url request error:" + url, e);
        } finally {
            method.releaseConnection();
        }
        return null;
    }

    public static String getDataAsStringFromPostUrl(String url, Map<String, String> map, int timeout,
                                                    Map<String, Object> httpMethodParams) {
        Assert.hasText(url, "url can not be blank!");
        HttpClient httpClient = new HttpClient(httpConnectionManager);
        // 连接超时
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(3000);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout);
        // 等待数据返回超时
        httpClient.getParams().setSoTimeout(timeout);
        PostMethod method = new PostMethod(url);
        // 默认是utf8,可以用参数httpMethodParams更改
        method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, DEFAULT_CHARSETNAME);

        if (null != httpMethodParams) {
            for (Map.Entry<String, Object> entry : httpMethodParams.entrySet()) {
                method.getParams().setParameter(entry.getKey(), entry.getValue());
            }
        }

        if (null != map) {
            for (Map.Entry<String, String> entry : map.entrySet()) {
                method.setParameter(entry.getKey(), entry.getValue());
            }
        }

        try {
            int statusCode = httpClient.executeMethod(method);
            if (statusCode == HttpStatus.SC_OK) {
                return new String(method.getResponseBody(), DEFAULT_CHARSETNAME);
            } else {
                throw new RuntimeException("http request error,return code:" + statusCode + ",msg:"
                                           + new String(method.getResponseBody()));
            }
        } catch (HttpException e) {
            logger.error(e.getMessage());
        } catch (IOException e) {
            logger.error(e.getMessage());
        } finally {
            // Release the connection.
            method.releaseConnection();
        }
        return new RuntimeException("Exception appear in httpClient");
    }
}

异步httpClient

反之相对同步httpclient,如果请求response的RT时间超出业务接受范围,则只能改用异步,需要一个callBack类来处理异步response


public class AsyncHttpClients {

    public static Logger           logger            = LoggerFactory.getLogger(AsyncHttpClients.class);
    private static final int       HTTP_CODE_SUCCESS = 200;
    private static AsyncHttpClient asyncHttpClient;

    static {
        DefaultAsyncHttpClientConfig.Builder configBuilder = new DefaultAsyncHttpClientConfig.Builder();
        configBuilder.setMaxConnections(20000);
        configBuilder.setMaxConnectionsPerHost(200);
        configBuilder.setReadTimeout(3000);
        configBuilder.setRequestTimeout(3000);
        configBuilder.setConnectTimeout(1000);
        configBuilder.setMaxRequestRetry(0);
        configBuilder.setTcpNoDelay(true);
        configBuilder.setDisableUrlEncodingForBoundRequests(true);
        configBuilder.setThreadPoolName("AsyncHttpClients");
        DefaultAsyncHttpClientConfig cf = configBuilder.build();
        asyncHttpClient = new DefaultAsyncHttpClient(cf);
    }

    public static void postUrlFormBody(String url, AsyncHttpClientCallBack callback) {
        postUrlFormBody(url, null, callback);
    }
    /**
     * 异步任务
     * @param url
     * @param paramMap
     * @param callback
     */
    public static void postUrlFormBody(final String url, Map<String, String> paramMap,
                                       final AsyncHttpClientCallBack callback) {
        // 构造请求参数
        List<Param> params = new ArrayList<>();
        if (!CollectionUtils.isEmpty(paramMap)) {
            Iterator<String> itr = paramMap.keySet().iterator();
            while (itr.hasNext()) {
                String name = itr.next();
                params.add(new Param(name, paramMap.get(name)));
            }
        }
        // 发送异步请求
        asyncHttpClient.preparePost(url).addQueryParams(params).execute(new AsyncCompletionHandler<Response>() {

            @Override
            public Response onCompleted(Response response) throws Exception {
                if (response.getStatusCode() == HTTP_CODE_SUCCESS) {
                    callback.requestCompleted(true, response.getResponseBody(), null);
                } else {
                    callback.requestCompleted(false, null,
                                              "request error,http code:" + response.getStatusCode() + ",url:" + url);
                }
                return null;
            }

            @Override
            public void onThrowable(Throwable t) {
                callback.requestCompleted(false, null, "request error,url:" + url + ",case by " + t.getMessage());
            }
        });
    }
}

----------------------分割线----------------------------
/** 处理异步response的callBack函数 **/
public interface AsyncHttpClientCallBack {
    void requestCompleted(boolean success, String data, String errorMsg);
}

使用

public class HttpclientTest {

    @Test
    public void syncHttpclientTest() {
        String url = "http://127.0.0.1/api.do";
        /** HTTP GET **/
        // Sync
        String syncGet = SyncHttpClients.getDataAsStringFromUrl(url);
        // Async
        AsyncHttpClients.postUrlFormBody(url, new AsyncHttpClientCallBack() {

            @Override
            public void requestCompleted(boolean success, String data, String errorMsg) {
                if (success) {
                    // TODO 处理code为200的data数据
                } else {
                    // TODO 处理code非200的错误数据
                }
            }
        });

        /** HTTP POST **/
        HashMap<String, String> paramMap = new HashMap<String, String>() {

            {
                put("key", "value");
            }
        };
        String responsePost = SyncHttpClients.getDataAsStringFromPostUrl(url, paramMap);
        AsyncHttpClients.postUrlFormBody(url, paramMap, new AsyncHttpClientCallBack() {

            @Override
            public void requestCompleted(boolean success, String data, String errorMsg) {
                if (success) {
                    // TODO 处理code为200的data数据
                } else {
                    // TODO 处理code非200的错误数据
                }
            }
        });
    }
}

没有更多推荐了,返回首页