Автор оригинала: Eugen Paraschiv.
1. Обзор
В этой статье мы покажем, как сократить URL-адреса с помощью |/HttpClient .
Простой пример-это когда исходный URL-адрес был сокращен один раз – службой, такой как bit.лы .
Более сложный пример-это когда URL-адрес был сокращен несколько раз различными такими службами , и требуется несколько проходов, чтобы добраться до исходного полного URL-адреса.
Если вы хотите копнуть глубже и узнать другие интересные вещи, которые вы можете сделать с помощью HttpClient – перейдите к основному учебнику HttpClient .
2. Один раз откорректируйте URL-адрес
Давайте начнем с простого – разрежьте URL-адрес, который был передан через службу сокращения URL-адресов только один раз.
Первое, что нам понадобится, – это http-клиент, который не будет автоматически следовать перенаправлениям :
CloseableHttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();
Это необходимо, потому что нам нужно будет вручную перехватить ответ на перенаправление и извлечь из него информацию.
Мы начинаем с отправки запроса на сокращенный URL – адрес-ответ, который мы получим, будет 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-Адресов
Проблема с короткими URL-адресами заключается в том , что они могут быть сокращены несколько раз совершенно разными службами. Для расширения такого URL-адреса потребуется несколько проходов, чтобы добраться до исходного URL-адреса.
Мы собираемся применить развернуть одноуровневую примитивную операцию, определенную ранее, чтобы просто перебрать все промежуточные 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)); }
На этот раз короткий URL – адрес – http://t.co/e4rDDbnzmk – который на самом деле сокращается дважды – один раз через бит.ly и во второй раз через t.co сервис – правильно расширен до исходного URL-адреса.
4. Обнаружение в циклах перенаправления
Наконец, некоторые URL-адреса не могут быть расширены, поскольку они образуют цикл перенаправления. Этот тип проблемы будет обнаружен HttpClient , но поскольку мы отключили автоматическое отслеживание перенаправлений, он больше не работает.
Последним шагом в механизме расширения URL-адресов будет обнаружение циклов перенаправления и быстрый сбой в случае возникновения такого цикла.
Чтобы это было эффективно, нам нужна дополнительная информация из метода expandSingleLevel , который мы определили ранее – в основном, нам также нужно вернуть код состояния ответа вместе с URL-адресом.
Поскольку java не поддерживает несколько возвращаемых значений, мы собираемся обернуть информацию в org.apache.commons.lang3.tuple.Pair object – теперь новая сигнатура метода будет:
public PairexpandSingleLevelSafe(String url) throws IOException {
И, наконец, давайте включим обнаружение цикла перенаправления в основной механизм расширения:
public String expandSafe(String urlArg) throws IOException { String originalUrl = urlArg; String newUrl = expandSingleLevelSafe(originalUrl).getRight(); ListalreadyVisited = 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. Заключение
В этом уроке обсуждалось, как развернуть короткие URL – адреса в java – с помощью Apache HttpClient .
Мы начали с простого варианта использования с URL-адресом, который сокращается только один раз, а затем реализовали более общий механизм, способный обрабатывать несколько уровней перенаправлений и обнаруживать циклы перенаправления в процессе.
Реализацию этих примеров можно найти в проекте github – это проект, основанный на Eclipse, поэтому его должно быть легко импортировать и запускать как есть.