Jetty を使ってWeb サーバを立ち上げ、更にSSL 接続を実装する
最近、Jetty を使ってJava でWeb サーバを立ち上げたので、その方法について備忘録的に書きます。
Jetty ?
Jetty は、100%JavaのJava Servletコンテナ・Webサーバである。WebSocketなどのプロトコルもサポートする。Jetty はオープンソースプロジェクトとして開発され、Apache 2.0 License でリリースされている。JBoss、Apache Geronimoといった他のプロジェクトでも利用されている。Wikipedia によると以上の通りだそうです。
単純で効率的な組み込みやすいWebサーバとなるよう意図して開発されている。サイズが小さいので、組み込み型 Java アプリケーションにWebサービスを提供するのに適している。 Jetty - Wikipedia
つまり、Jetty の特徴を砕いて言うと
- サーバの実装がかなり簡単 (←本当に)
- Java だからクロスプラットフォーム
- WebSocket に対応していてかなり嬉しい! (WebSocket を使う必要があったので)
と言うわけで、Jetty をつかってWeb サーバを立ち上げる運びとなりました。
下ごしらえ
今回はJetty を利用するに当たって、Maven を使いました。なので、Maven のpom.xml に適宜設定を記述する必要があります。
maven2からjetty6を起動するメモ - maeda.na@はてな
や、
http://jyukutyo.hatenablog.com/entry/20101216/1292511146
を参考にして頂ければ大丈夫だと思います。
普通にHTTP 接続できるサーバをJava で書く
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; private void establishHttpServer() { HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[] { new DefaultHandler() }); // 他のハンドラが必要な場合はそれらも引数として与える。例えばWebSocket のハンドラとか。 Server server = new Server(12345); // 引数には任意のポート番号を入れる。入れないとデフォルトの8080 番ポートが使用される(はず) server.setHandler(handlers); }上のコード例の場合は12345 番ポートで利用可能なWeb サーバが立ち上がります。
SSL 接続できるサーバをJava で書く
SSL 接続に係る設定等は以下を参照下さい。Jetty/Howto/Configure SSL - Eclipsepedia
JettyでSSL for Windows 〜オレオレ証明書編 - Take action for the Future.
今回はオレオレ証明書を使う事にします。
keystore ファイルは出来ている前提です。
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; private void establishSslServer() { HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[] { new DefaultHandler() }); File keystoreFile = new File(/*keystore のロケーション*/); Server server = null; if(keystoreFile.exists()) { // SSL server = new Server(); SslSelectChannelConnector sslConnector = new SslSelectChannelConnector(); sslConnector.setPort(12345); // 任意のポート番号 sslConnector.setKeystore(keystoreFile.getPath()); sslConnector.setPassword(/*キーストアのパスワード*/); sslConnector.setKeyPassword(/*パスワード*/); server.addConnector(sslConnector); } else { server = new Server(12345); } server.setHandler(handlers); }上のコード例の場合、keystore ファイルが存在している時は12345 ポートでSSL 接続が可能となり、
keystore ファイルが無い場合は12345 ポートでHTTP 接続が出来るようになります。
SSL 接続と非SSL 接続をハイブリッドしたサーバをJava で書く
先ほど書いた"establishSslServer()"はSSL 接続と非SSL 接続の切り替えが出来ないので、少し不便です。8888 ポートで接続された場合は普通の非SSL 接続、9999 ポートで接続された場合はSSL 接続を行うように書き換えます。
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.server.ssl.SslSelectChannelConnector; private void establishWebServer() { HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[] { new DefaultHandler() }); File keystoreFile = new File(/*keystore のロケーション*/); this.server = new Server(); SelectChannelConnector connector = new SelectChannelConnector(); connector.setPort(8888); server.setConnectors(new Connector[]{connector}); if(keystoreFile.exists()) { // SSL SslSelectChannelConnector sslConnector = new SslSelectChannelConnector(); sslConnector.setPort(9999); sslConnector.setKeystore(keystoreFile.getPath()); sslConnector.setPassword(/*キーストアのパスワード*/); sslConnector.setKeyPassword(/*パスワード*/); this.server.addConnector(sslConnector); } this.server.setHandler(handlers); }これで上記の条件を満たすWeb サーバを立ち上げることが可能です。