httpclient 设置短连接_HttpClient 还原缩短URL地址(提高篇)

1.概述

在本文中,我们将演示如何使用 HttpClient解除URL的绑定。

一个简单的例子就是当原始URL被缩短一次 - 通过诸如bit.ly的服务。

一个更复杂的例子是,URL被多次缩短,被不同的服务缩短,并且需要多次才能到达原始的完整URL。

2.暂停URL一次

让我们从简单的开始 - 取消暂停仅通过一次缩短的URL服务传递的URL。

首先我们需要的是一个不会自动遵循重定向的http客户端:

CloseableHttpClient client =

HttpClientBuilder.create().disableRedirectHandling().build();

这是必要的,因为我们需要手动拦截重定向响应并从中提取信息。

我们首先发送一个请求到缩短的网址 - 我们得到的回应将是一个301永久移动。

然后,我们需要提取指向下一个的位置标题,在这种情况下 - 最终的URL:

public String expandSingleLevel(String url) throws IOException {

HttpHead request = null;

try {

request = new HttpHead(url);

HttpResponse httpResponse = client.execute(request);

int statusCode = httpResponse.getStatusLine().getStatusCode();

if (statusCode != 301 && statusCode != 302) {

return url;

}

Header[] headers = httpResponse.getHeaders(HttpHeaders.LOCATION);

Preconditions.checkState(headers.length == 1);

String newUrl = headers[0].getValue();

return newUrl;

} catch (IllegalArgumentException uriEx) {

return url;

} finally {

if (request != null) {

request.releaseConnection();

}

}

}

最后,一个简单的现场测试扩展一个URL:

@Test

public void givenShortenedOnce_whenUrlIsUnshortened_thenCorrectResult() throws IOException {

String expectedResult = "/rest-versioning";

String actualResult = expandSingleLevel("http://bit.ly/13jEoS1");

assertThat(actualResult, equalTo(expectedResult));

}

3.处理多个URL级别

短网址的问题在于,它们可能会被完全不同的服务缩短多次。展开这样的网址需要多次传递才能访问原始网址。

我们将应用先前定义的expandSingleLevel基元操作来简单地遍历所有中间URL并达到最终目标:

public String expand(String urlArg) throws IOException {

String originalUrl = urlArg;

String newUrl = expandSingleLevel(originalUrl);

while (!originalUrl.equals(newUrl)) {

originalUrl = newUrl;

newUrl = expandSingleLevel(originalUrl);

}

return newUrl;

}

现在,通过扩展多个URL级别的新机制,我们定义一个测试并使其工作:

@Test

public void givenShortenedMultiple_whenUrlIsUnshortened_thenCorrectResult() throws IOException {

String expectedResult = "/rest-versioning";

String actualResult = expand("http://t.co/e4rDDbnzmk");

assertThat(actualResult, equalTo(expectedResult));

}

这一次,短网址 - http://t.co/e4rDDbnzmk - 实际上缩短了两次 - 一次通过bit.ly,第二次通过t.co服务 - 正确地扩展到原始URL。

4.检测重定向循环

最后,一些URL不能被扩展,因为它们形成了重定向循环。这种类型的问题会被HttpClient检测到,但是由于我们关闭了重定向的自动跟踪,因此不再这样做。

URL扩展机制的最后一步是检测重定向循环,并在发生这种循环时快速失败。

为了使其有效,我们需要使用前面定义的expandSingleLevel方法提供一些附加信息- 主要是我们还需要返回响应的状态代码和URL。

由于java不支持多个返回值,我们将把这些信息包装在一个org.apache.commons.lang3.tuple.Pair对象中 - 方法的新签名现在是:

public Pair expandSingleLevelSafe(String url) throws IOException {}

最后,让我们在主扩展机制中包含重定向周期检测:

public String expandSafe(String urlArg) throws IOException {

String originalUrl = urlArg;

String newUrl = expandSingleLevelSafe(originalUrl).getRight();

List alreadyVisited = Lists.newArrayList(originalUrl, newUrl);

while (!originalUrl.equals(newUrl)) {

originalUrl = newUrl;

Pair statusAndUrl = expandSingleLevelSafe(originalUrl);

newUrl = statusAndUrl.getRight();

boolean isRedirect = statusAndUrl.getLeft() == 301 || statusAndUrl.getLeft() == 302;

if (isRedirect && alreadyVisited.contains(newUrl)) {

throw new IllegalStateException("Likely a redirect loop");

}

alreadyVisited.add(newUrl);

}

return newUrl;

}

就是这样 - expandSafe机制可以通过任意数量的URL缩短服务取消递交URL,同时在重定向循环中正确地失败。

5.总结

本教程讨论了如何使用Apache HttpClient扩展java中的短URL。

我们从一个简单的用例开始,只使用一次缩短的URL,然后实现一个更通用的机制,能够处理多个重定向级别并检测流程中的重定向循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值