木头人
2017-10-09 21:35:54
httpclient开发遇到的坑
一个需求要调用第三方接口,在postman上测试的时候,可以说是秒开的,非常流畅,但是后台代码却一直卡在了httpclient.execute()这个方法上了,过了10多秒后给我报了个connecttion time out的异常。我蒙蔽了半天。我查看了一些网上别人写的代码,和自己的对比了半天也不知道神魔问题。开始我怀疑是版本问题,我删除了4.2版本的jar包,代码修改为4.3的语法结果还是一样的问题。就这样反复的折腾一直整个下午也没搞出来,然后问了下公司的一个哥们。他最后给我发了一个web.xml的配置,解决跨域的问题,然后对我说这是总结的经验,就这样做很坚定地告诉我。我郁闷了半天。这是在逗我吗。我写的后台代码,根本就没经过前台发出的请求和跨域有毛线关系。当然这只是心里的想法,还是谢谢哥们的好心。
最后发现cmd 命令行里面也ping不通,连百度也不能ping通。我才想起来,原来一直用的是公司的云办公,访问的外网都是要通过代理的。这操蛋的调用第三方接口肯定在后台代码也要用代理。然后搜索了一下,果然httpclient有调用代理的方法:
HttpHost targetHost = new HttpHost("localhost", 80, "http"); CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials("username", "password")); // Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme object and add it to the local auth cache BasicScheme basicAuth = new BasicScheme(); authCache.put(targetHost, basicAuth); // Add AuthCache to the execution context HttpClientContext context = HttpClientContext.create(); context.setCredentialsProvider(credsProvider); context.setAuthCache(authCache); CloseableHttpResponse response = httpclient.execute( targetHost, httpget, context); try { HttpEntity entity = response.getEntity(); } finally { response.close(); }
离成功更进一步,不报connection time out 的异常了,但是返回说代理问题,不管怎麽说问题解决了,代理的问题,后面继续定位是不是账号或密码有问题。
后来发现是不加content就行了,更新代码如下:
/** * * @param url * @param host * @param port * @param account * @param password * @return */ public static String sendViaProxy(String url, String host, int port, String account, String password) { HttpHost proxy = new HttpHost(host, port, "http"); CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials( new AuthScope(proxy.getHostName(), proxy.getPort()), new UsernamePasswordCredentials(account, password)); CloseableHttpClient httpClient = HttpClients.custom() .setDefaultCredentialsProvider(credentialsProvider) .build(); RequestConfig config = RequestConfig.custom() .setConnectTimeout(3000) .setConnectionRequestTimeout(3000) .setProxy(proxy) .build(); HttpGet request = new HttpGet(url); request.setConfig(config); try { HttpResponse httpResponse = httpClient.execute(request); if (httpResponse.getStatusLine().getStatusCode() == 200) { return EntityUtils.toString(httpResponse.getEntity(), "utf-8"); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
评论