##はじめに
この記事は、リンク情報システムが主催するイベント「Tech Connect! Autumn」のリレー記事です。
「Tech Connect! Autumn」は engineer.hanzomon のグループメンバによってリレーされます。
(リンク情報システムのFaceBookはこちらから)
5日目となります本日は「Eclipse+Tomcatでhttp2開発環境構築してみた」という記事を@usankusaiが投稿いたします。
##きっかけ
当初、今回のイベントを聞いた時には、前から興味のあったリアルタイム通信、特にWebsocketやポーリングごとの仕組みや実装の違いを調査した記事にしようかなと考えていました。
が、qiitaに投稿されている@kimullaaさんの記事、リアルタイムなwebアプリを実現する方法(ポーリング、Comet、Server Sent Events、WebSocket)にて図解とサンプルコードによる超絶分かりやすい記事が既に作成されていたので、別の内容にすることにしました。
上記の記事の「実装してみた感想」の末尾にてリンクされている、POSTDさんの翻訳記事「WebSocketには注意が必要」にて、WebSocket通信の注意点と、その対案としてHTTP2.0によるポーリングやメッセージングの紹介が記載されています。
私も元々「リアルタイム通信ってなんだかんだ言ってもWebSocketだよなぁ」とか安易に考えていたので、POSTDさんの記事を見て「安易にWebSocket選んじゃダメなのか。というか、HTTP2.0ってよく聞くけどどんな機能あるんだろう。そもそもどうやって開発環境作るんだ・・・?」という疑問がふつふつと湧いてきたので、今回のイベントでhttp2.0の開発環境を作成してみることにしました。
##概要
Eclipse + Tomcatでhttp2開発環境を作成する手順について、私が試してみた流れで記載をしてみます。
ただしhttp2通信ができていることのみを確認した環境なので実用性は不明です。あしからず。
##必要環境
1:Eclipse
-今回の記事ではEclipse PhotonのPleiades All in One(Java FullEdition)を使用しました。
Pleiades All in One ダウンロードページ
2:Tomcat
-今回の記事では1のPleiades All in Oneに含まれているTomcat9.0.10を使用しました。
-Tomcatの公式ページを確認するとバージョンごとにhttp2の動作要件が異なっているようです。
-Ver8.5.xの場合
Apache Tomcat 8.5.x includes the following significant improvements:
•Adds support for HTTP/2 (requires the Tomcat Native library)
-Ver9.xの場合
•Adds support for HTTP/2 (requires either running on Java 9 (since Apache Tomcat 9.0.0.M18) or the Tomcat Native library being installed)
ver8.5.xまではTomcat以外にTomcat Native libraryが別途必要になるようですが、ver9.xではTomcat Native libraryが無くてもJava9を入れることでhttp2通信が可能になるようです。
今回の記事ではTomcat Native libraryは使用しない実装でhttp2通信を実現します。
3:JDK
-今回の記事では1のPleiades All in Oneに含まれているJDK10.0.1を使用しました。
4:OpenSSL
-今回の記事ではhttps通信でhttp2を実装します。テスト用に自己署名証明書(いわゆるオレオレ証明書)を発行してhttps通信を実現します。
-atmarkitさんの記事を参考に、Shining Light Productionsさんのページで公開されているWin64 OpenSSL v1.1.0iをインストールしました。
→Win32 OpenSSLのダウンロードページ
##前準備
あらかじめEclipseは適当なフォルダに解凍を行い、OpenSSLはインストール&Pathの設定を完了した状態にしてください。
これらの手順は先述したatmarkitさんの記事にて丁寧に解説されています。
##OpenSSLを使用してhttps通信に必要なファイルを発行する
最初にOpenSSLを使用してテスト用の自己署名証明書を発行します。
コマンドプロンプトを起動し、下記のコマンドを実行するとカレントディレクトリーに公開鍵(証明書)であるtomcat.crtと秘密鍵であるtomcat.keyが出力されます。
C:\>
openssl req -newkey rsa:2048 -nodes -keyout tomcat.key -subj "/C=JP/ST=Saitama/L=Saiatama/O=hogehoge/CN=localhost" -x509 -days 365 -out tomcat.crt
.+++
............................+++
writing new private key to 'tomcat.key'
-----
更に上記で生成された2ファイルを元にPKCS#12形式の個人情報交換ファイルtomcat.pfxを作成します。
C:>
openssl pkcs12 -inkey tomcat.key -in tomcat.crt -export -out tomcat.pfx
コマンド実行後、暗号化のパスワードの入力を求められるため、入力を行います。(記事では仮に'123456'としておきます)
Enter Export Password:
Verifying - Enter Export Password:
上記の手順で下記三つのファイルが生成されていれば、https通信に必要なファイルは準備完了となります。
##ブラウザに個人情報交換ファイルと証明書をインポートする。
######個人情報交換ファイルのインポート
今回作成するテスト用ページをブラウザで表示する場合は、ブラウザ側に自己署名証明書をインポートする必要があります。
インポートされていない場合、例えばIE(Internet Explorer)のケースだと下記のように表示され、テストページを表示することができません。
証明書をインポートする手順はブラウザによって異なりますが、IEの場合での手順は下記の通りとなります。
まずは[ツール]→[インターネットオプション]を選択します。
ポップアップ表示されたインターネットオプションウィンドウの[コンテンツ]タグを選択し、[証明書]ボタンを押下します。
証明書ウィンドウがポップアップされるので、[個人]タブが選択状態になっていることを確認し、[インポート]ボタンを押下します。
インポートウィザードが表示されるので[次へ]ボタンを押下します。
インポートする証明書ファイルを要求されるので、先ほど作成した個人情報交換ファイルtomcat.pfxを選択し、[次へ]ボタンを押下します。
※pfxファイルが表示されない場合、右下のファイルフォーマットを変更することでpfxファイルを表示させることができます。
pfxファイル出力時に入力したパスワードの入力を求められるので、パスワードを入力して[次へ]ボタンを押下します。
ファイルを保管する証明書ストアとして[個人]が選択されていることを確認して、[次へ]ボタンを押下します。
証明書ウィンドウに戻ってくるので、[個人]タブに発行先が「localhost」の証明書が登録されていれば個人情報交換ファイルのインポートは完了となります。
######証明書のインポート
続いて証明書をインポートします。
証明書ウィンドウの[信頼されたルート証明機関]タブを選択し、[インポート]ボタンを押下します。
ここからは基本的に個人情報交換ファイルのインポートと同様の手順ですが、インポートするファイルとしてtomcat.crtを選択してください。
証明書インポート ウィザードの完了で[完了]ボタンを押すと、下記のようなダイアログが表示される場合がありますので[はい]を選択してください。
証明書ウィンドウに戻ってくるので、[信頼されたルート証明機関]タブに発行先が「localhost」の証明書が登録されていれば証明書のインポートも完了となります。
##EclipseからTomcatのデバッグサーバを起動する
次にEclipseの設定です。
まずはEclipseを起動します。
まずはJDKの設定とTomcatのランタイム環境の構成を設定します。
[ウィンドウ]→[設定]を選択し、
設定ウィンドウの[Java]ツリーの中にある、[インストール済みのJRE]を選択し、右側の画面の[追加]ボタンを押下します。
JREの型に[標準VM]が選択されていることを確認し、[次へ]ボタンを押下します。
JREの定義にて、JREホームにpleiades内のjavaフォルダにあるJDK10のルートディレクトリを選択し、JREシステム・ライブラリーに「jrt-fs.jar」が追加されていることを確認して[完了]ボタンを押下します。
設定ウィンドウに戻ると、インストール済みのJREに先ほど追加した
JDK10が表示されているので、これを選択した状態で[適用]ボタンを押下します。
これでJDKの設定は完了です。
次にTomcatのランタイム環境の設定と、デバッグサーバの構築を行います。
設定ウィンドウの[サーバー]ツリーの中にある、[ランタイム環境]を選択し、右側の画面の[追加]ボタンを押下します。
ランタイム環境のタイプに[Apache Tomcat v9.0]を選択し、[新規ローカル・サーバー作成]にチェックをした状態で[次へ]ボタンを押下します。
Tomcatインストールディレクトリーにpleiadesに含まれていたTomcat9のルートディレクトリーを、JREのプルダウンから先述の手順で追加したJDK10を選択し、[完了]ボタンを押下します。
設定ウィンドウに戻るとサーバー・ランタイム環境にApache Tomcat V9.0が追加されているので、[適用して閉じる]ボタンを押下してウィンドウを閉じます。
Eclipse IDEのウィンドウに戻るので、画面下部の[デバッグ]タブをクリックしてTomcat V9.0のデバッグサーバが登録されていることを確認します。
最後にデバッグサーバを起動し、起動処理が問題なく実行されることを確認します。
[デバッグ]タブに追加されたTomcat V9.0サーバを右クリックし、コンテキストメニューから[デバッグ]を選択します。
選択後、[コンソール]タブをクリックすると起動時の処理の実行結果が表示されるため、
下記のエビデンスのように
・情報区分のメッセージのみが表示されていること(エラーが発生した場合、警告や重大区分のメッセージが表示されます)
・最後のメッセージが「Server startup in ~」となっていること
を確認します。
上記の通りになっていれば、デバッグサーバが無事起動できている状態となります。
##サンプルページを実装して使用しているプロトコルを確認する。
続いて使用しているプロトコルを確認するサンプルページを実装します。
まずはEclipseにサンプルページを表示するためのプロジェクトを追加します。
Eclipse左側のプロジェクト・エクスプローラー上で右クリックを押下し、コンテキストメニューから[新規]→[動的 Web プロジェクト]を選択します。
新規動的Webプロジェクトのウィンドウでプロジェクト名に「TestProject」と入力して、[完了]ボタンを押下します。
プロジェクト・エクスプローラーにTest Projectが追加されるので、TestProjectを展開して「WebContent」で右クリックを押下し、開いたコンテキストメニューから[新規]→[JSPファイル]を選択します。
新規JSPファイルウィンドウにて、ファイル名を「index.jsp」に変更して[完了]ボタンを押下します。
するとEclipse画面の中央に、index.jspのタブが表示されます。
ここでindex.jspの中身を下記のように書き換えて上書き保存をしてください。
<%@ page contentType="text/html; charset=utf-8" %>
<% String protocolStr = request.getProtocol(); %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>プロトコル確認</title>
</head>
<body>
<h1>プロトコル確認</h1>
<table border=1>
<tr><td>プロトコル</td></tr>
<tr><td>
<%= protocolStr %>
</td></tr>
</table>
</body>
</html>
上記jspを保存、eclipse下部の[サーバー]タブより、起動中のデバッグサーバを右クリックし、コンテキストメニューから[追加及び除去]を選択します。
追加及び除去ウィンドウにて、使用可能欄にあるTestProjectを選択し、[追加]ボタンを押下してください。
TestProjectが使用可能欄から構成済み欄に移動したのを確認してから[完了]ボタンを押下
デバッグサーバのステータスに[デバッグ,再開]と表示されているのを確認し、右クリックでコンテキストメニューを表示します。
続けてコンテキストメニューから「デバッグで再起動」を選択してください。
[コンソール]タブを選択し、先ほどと同じように特にエラーが出力されることなく、サーバの起動が完了していることを確認します。
これでデバッグサーバ上にテスト用のページを配置することが出来ました。
早速ブラウザからテスト用ページを表示します。
テスト用のページには下記のアドレスでアクセス可能です。>http://localhost:8080/TestProject/index.jsp
ブラウザ上で表示すると、下記のような画面が表示されると思います。
画面に表示されているように、現在の状態だと「HTTP/1.1」をプロトコルを接続した状態であることが分かります。
これで(ようやく)テスト用のページまでを導入することができました。
次の手順でいよいよhttp2通信を実装します。
##http2通信用のコネクタを実装する。
Eclipseに戻り、プロジェクト・エクスプローラにある[Servers]フォルダ→[ローカルホスト の Tomcat v9.0 サーバー-config]フォルダを展開し、[server.xml]をダブルクリックして開きます。
おそらく初期状態では上記のように[デザイン]表示になっているはずなので、server.xmlタブの下部にある[ソース]タブをクリックして下記のようなソース表示に変更します。
ソースの中から先ほどのテスト用ページの表示に使用した、HTTP1.1プロトコル用のConnectorタグを見つけます。
上記の記述の直後に、下記のHTTP2プロトコル用のConnector設定を追記し、上書き保存をしてください。
<Connector port="8543" SSLEnabled="true"
protocol="org.apache.coyote.http11.Http11NioProtocol"
sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation">
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/tomcat.pfx" certificateKeystorePassword="123456"/>
</SSLHostConfig>
</Connector>
※上記の設定はgithubに投稿されているhasalexさんの投稿を参考に設定しました。
上記を保存後、
保存するとデバッグサーバのステータスが[デバッグ,再開]ステータスに変わっていると思いますので、先ほどの起動時と同じようにコンテキストメニューから[デバッグで再起動]を選択します。
これでhttp2プロトコルでの通信が可能となりました。
##http2通信でテスト用ページを表示
では、http2通信でテスト用ページを表示します。
先ほどはHTTP1.1の通信だったため、「http~」のアドレスでしたが、今回の実装したHTTP2の通信ではhttpsで接続をするため、アドレスが下記のように変わります。
アドレスにアクセス後、下記のようにプロトコルが「HTTP/2.0」と表示されれば実装完了となります。
念のためIEの開発者ツールでも通信のプロトコルを確認してみます。
IEを開いた状態で[F12]キーを押下します。
[ネットワーク]タブを選択し、[(再生みたいな形をした)]ボタンを押下します。
上記のボタンを押下すると、[(再生みたいな形をした)]ボタンが[(停止みたいな形をした)]ボタンに変わるので、この状態で再度テスト用のページにアクセスします。
テストページへアクセスすると、開発者ツールのネットワークに下記のように表示が追加されます。
ここのプロトコルも「HTTP/2」になっていますね。
##感想
まずは技術面から。
Eclipse + Tomcat自体は今まで何度か使用しているためそこまで苦労しませんでしたが、OpenSSLは初体験でここは少し苦労しました。
正直今回もHTTP2.0の環境を作るためとりあえず、というところしか調べられてませんが、折を見てもう少しここら辺の知識も深めようかなと思います。
本来の目的はこの環境でHTTP2.0の機能を色々と試すことなので、そこに関しても機会があれば記事を書きたいですね。
そして記事作成について。
qiitaはROM専ながら普段からお世話になってましたが、いざ記事を作るとなるとこんなにも大変なんだなぁと痛感しました、当たり前ですが;
特に記事の内容を決めてから、じゃあどう要約するか、という点でかなり悩みました。
なので今回は要約をほぼ諦めて、自分が実施した手順をそのまま記載するという形で記事を作成しています。
・・・が、当然ながらここまで書くと当然書く量が増えるので、物理的に苦労する結果となりました;
今度また記事を書く機会があれば、読む人の為にも、そして書く人(自分)のためにももう少しかいつまんだ記事にしようと思います...。
##参考ページ
記事の中に記載しているものもありますが、
今回の記事作成では下記のページを参考にさせて頂きました(敬称略)
-atmarkit WindowsにOpenSSLをインストールして証明書を取り扱う(基本編)
-hasalex/create-cert.sh(github)
-[JavaDrive リクエスト方法の取得(getScheme)]
(https://www.javadrive.jp/servlet/request/index7.html)