第21夜 あなたはJDK6のHTTPサーバを使っているか?

JavaでのWebサーバーといえばJavaEEに含まれるServlet APIを利用することが多いと思う。

しかし、そこまで大げさでなくとも・・・という用途は結構あるはずだ。

JDKに簡易Webサーバーが付属しているのを知っているだろうか。


http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/net/enhancements-6.0.html
一番下にある部分がそれだ。


以下サンプル

public class App {

    public static void main(String[] args) throws IOException {
        HttpServer server = HttpServerProvider.provider().createHttpServer(
                new InetSocketAddress("localhost", 80)
                , 0);

        server.createContext("/a" , new HttpHandler() {
            @Override
            public void handle(HttpExchange he) throws IOException {
                he.sendResponseHeaders(200, 0);
                OutputStream os = he.getResponseBody();
                os.write("/a".getBytes("UTF-8"));
                os.close();
            }
        });

        server.createContext("/a/b" , new HttpHandler() {
            @Override
            public void handle(HttpExchange he) throws IOException {
                he.sendResponseHeaders(200, 0);
                OutputStream os = he.getResponseBody();
                os.write("/a/b".getBytes("UTF-8"));
                os.close();
            }
        });

        server.start();
    }
}

いわゆるサーブレットやアクションに相当する部分を2つ登録している。見てわかると思うがsendResponseHeadersでHTTPステータスをセットする。省略しているが、server.stop()で終了する。スレッドが残っているのでmainが終わっても終了しない。プロセスを殺そう。

1つ目の「/a」というマッピングは「/abc」も「/a/c」もマッピングされる。
2つ目の「/a/b」というマッピングは1つ目と重なるように見えるが、一致する部分が長いこちらがちゃんと優先される。「/a/b/c」だと2つ目のほうが呼び出される。


単純な転送では十分に役立つ。mainから実行させるため追いやすい。


T2Frameworkのようなシンプルなものはこういったサーバーからも起動できると楽しいかも。

ちなみにJAX-RSのRIであるJerseyのサーバーはこのシンプルサーバも利用可能(もちろんサーブレットコンテナも可能だし、Grizzly WEB Server、Light weight HTTP serverも利用可能)。サーブレットコンテナが必要ないのでテスト等開発が非常にしやすい。そのうち紹介しよう。非常にシンプルに高機能なものが扱える。

[追記]以下で続き書いた。
http://d.hatena.ne.jp/shin/20100831/p1