Java で HTTP リダイレクト先の URL を取得する

## 概要

- Java で HTTP リダイレクト先の URL を取得する

## Java 11 版

GetRedirect.java というファイル名で以下の内容を保存する。

```java
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Optional;

public class GetRedirect {

  public static void main(String[] args) throws Exception {

    // コマンドライン引数を取得
    String srcUrl = args[0];

    // リダイレクト先URLを取得
    Optional<String> redirectUrl = getRedirectUrl(srcUrl);

    // リダイレクト先URLを出力
    redirectUrl.ifPresent(url -> System.out.println(url));
  }

  // リダイレクト先 URL を取得する
  public static Optional<String> getRedirectUrl(String srcUrl) throws URISyntaxException, IOException, InterruptedException {

    // HTTP リクエスト情報を構築
    HttpRequest req = HttpRequest.newBuilder(new URI(srcUrl)).GET().build();

    // HTTP リクエスト
    // HttpClient は 4xx や 5xx でも例外が発生しないので注意
    HttpClient client = HttpClient.newBuilder()
      .version(HttpClient.Version.HTTP_1_1)
      .followRedirects(HttpClient.Redirect.NEVER) // 自動でリダイレクトしない設定
      .build();
    HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());

    // HTTP レスポンスから Location ヘッダを取得
    return res.headers().firstValue("location");
  }
}
```

Java 11 (AdoprOpenJDK 11.0.8) + macOS Catalina による実行例。

```
$ java GetRedirect.java https://bit.ly/3kmTOkc
https://t.co/yITSBp4ino
```

```
$ java GetRedirect.java https://t.co/yITSBp4ino
https://qiita.com/niwasawa
```

```
$ java GetRedirect.java https://qiita.com/niwasawa
```

## Java 8 版

GetRedirect.java というファイル名で以下の内容を保存する。

```java
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

public class GetRedirect {

  public static void main(String[] args) throws IOException {

    // コマンドライン引数を取得
    String srcUrl = args[0];

    // リダイレクト先URLを取得
    String redirectUrl = getRedirectUrl(srcUrl);

    // リダイレクト先URLを出力
    if (redirectUrl != null) {
      System.out.println(redirectUrl);
    }
  }

  // リダイレクト先 URL を取得する
  public static String getRedirectUrl(String srcUrl) throws IOException {
    // 4xx や 5xx でも例外が発生しないので注意
    HttpURLConnection con = (HttpURLConnection) new URL(srcUrl).openConnection();
    con.setRequestMethod("GET");
    con.setInstanceFollowRedirects(false); // 自動でリダイレクトしない設定
    con.connect();
    // HTTP レスポンスから Location ヘッダを取得
    String location = con.getHeaderField("location");
    con.disconnect();
    return location;
  }
}
```

Java 8 (AdoprOpenJDK 1.8.0_265) + macOS Catalina による実行例。

コンパイル。

```
$ javac GetRedirect.java
```

実行。

```
$ java GetRedirect https://bit.ly/3kmTOkc
https://t.co/yITSBp4ino
```

```
$ java GetRedirect https://t.co/yITSBp4ino
https://qiita.com/niwasawa
```

```
$ java GetRedirect https://qiita.com/niwasawa
```

## 参考資料

- [java\.net\.http \(Java SE 11 & JDK 11 \)](https://docs.oracle.com/javase/jp/11/docs/api/java.net.http/java/net/http/package-summary.html)
- [HttpURLConnection \(Java Platform SE 8 \)](https://docs.oracle.com/javase/jp/8/docs/api/java/net/HttpURLConnection.html)
- [HTTP のリダイレクト \- HTTP \| MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Redirections)
- [Location \- HTTP \| MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Location)