Urutkan URL dengan HttpClient

1. Ikhtisar

Di artikel ini kami akan menunjukkan cara memendekkan URL menggunakan HttpClient .

Contoh sederhana adalah ketika URL asli telah dipersingkat sekali - dengan layanan seperti bit.ly .

Contoh yang lebih kompleks adalah ketika URL telah dipersingkat beberapa kali , oleh layanan yang berbeda, dan dibutuhkan beberapa kali lintasan untuk sampai ke URL lengkap asli.

Jika Anda ingin menggali lebih dalam dan mempelajari hal-hal keren lainnya yang dapat Anda lakukan dengan HttpClient - lanjutkan ke tutorial HttpClient utama .

2. Unshorten URL Sekali

Mari kita mulai dengan sederhana - batalkan persingkat URL yang hanya pernah melewati layanan URL singkat satu kali.

Hal pertama yang kami perlukan adalah klien http yang tidak otomatis mengikuti pengalihan :

CloseableHttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();

Ini diperlukan karena kita perlu mencegat respons pengalihan secara manual dan mengekstrak informasi darinya.

Kita mulai dengan mengirimkan permintaan ke URL yang dipersingkat - tanggapan yang kita terima akan menjadi 301 Moved Permanently .

Kemudian, kita perlu mengekstrak tajuk Lokasi yang mengarah ke berikutnya, dan dalam kasus ini - URL final:

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(); } } }

Terakhir, uji langsung sederhana yang memperluas URL:

@Test public void givenShortenedOnce_whenUrlIsUnshortened_thenCorrectResult() throws IOException { String expectedResult = "/rest-versioning"; String actualResult = expandSingleLevel("//bit.ly/13jEoS1"); assertThat(actualResult, equalTo(expectedResult)); }

3. Memproses Beberapa Tingkat URL

Masalah dengan URL singkat adalah bahwa mereka dapat dipersingkat beberapa kali , oleh layanan yang sama sekali berbeda. Memperluas URL seperti itu akan membutuhkan banyak izin untuk sampai ke URL asli.

Kita akan menerapkan operasi primitif expandSingleLevel yang ditentukan sebelumnya untuk hanya melakukan iterasi melalui semua URL perantara dan sampai ke target akhir :

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; }

Sekarang, dengan mekanisme baru untuk memperluas beberapa level URL, mari kita tentukan tes dan menerapkan ini:

@Test public void givenShortenedMultiple_whenUrlIsUnshortened_thenCorrectResult() throws IOException { String expectedResult = "/rest-versioning"; String actualResult = expand("//t.co/e4rDDbnzmk"); assertThat(actualResult, equalTo(expectedResult)); }

Kali ini, URL singkat - //t.co/e4rDDbnzmk - yang sebenarnya dipersingkat dua kali - sekali melalui bit.ly dan kedua kalinya melalui layanan t.co - diperluas dengan benar ke URL aslinya.

4. Deteksi pada Redirect Loops

Terakhir, beberapa URL tidak dapat diperluas karena membentuk loop pengalihan. Jenis masalah ini akan terdeteksi oleh HttpClient , tetapi karena kami menonaktifkan ikuti otomatis pengalihan, hal itu tidak lagi terjadi.

Langkah terakhir dalam mekanisme perluasan URL adalah mendeteksi pengulangan pengalihan dan gagal dengan cepat jika terjadi pengulangan seperti itu.

Agar ini efektif, kami memerlukan beberapa informasi tambahan dari metode expandSingleLevel yang kami definisikan sebelumnya - terutama, kami juga perlu mengembalikan kode status respons bersama dengan URL.

Karena java tidak mendukung beberapa nilai kembalian, kita akan membungkus informasi dalam objek org.apache.commons.lang3.tuple.Pair - tanda tangan baru dari metode ini sekarang adalah:

public Pair expandSingleLevelSafe(String url) throws IOException {

Dan terakhir, mari sertakan deteksi siklus pengalihan dalam mekanisme perluasan utama:

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; }

Dan hanya itu - mekanisme expandSafe dapat memendekkan URL melalui sejumlah layanan pemendekan URL yang sewenang-wenang, sementara benar gagal dengan cepat pada pengalihan pengalihan.

5. Kesimpulan

Tutorial ini membahas cara memperluas URL singkat di java - menggunakan Apache HttpClient .

Kami mulai dengan usecase sederhana dengan URL yang hanya dipersingkat satu kali, lalu menerapkan mekanisme yang lebih umum, yang mampu menangani beberapa tingkat pengalihan dan mendeteksi loop pengalihan dalam prosesnya.

Penerapan contoh ini dapat ditemukan di proyek github - ini adalah proyek berbasis Eclipse, jadi semestinya mudah untuk mengimpor dan menjalankannya apa adanya.