WEBrickでHTTPサーブレットを作ってみる。
Ruby標準添付のWEBrickでHTTPサーブレットを作ってみました。まずはHelloWorld。WEBrickのサイトにあるサンプルのコピペです。
require 'webrick' include WEBrick # httpサーバー s = HTTPServer.new( :Port => 8080 ) # サーブレット class HelloServlet < HTTPServlet::AbstractServlet def do_GET(req, res) res['Content-Type'] = "text/html" res.body = "<html><body>hello world.</body></html>" end end # サーブレットをマウント s.mount("/hello", HelloServlet) # Ctrl + C で停止するようにトラップを仕込む。 trap(:INT){ s.shutdown } # サーバーを起動 s.start
スクリプトを実行して、「http://localhost:8080/hello」にブラウザでアクセスすると、「hello world.」が表示されます。「Ctrl + C」で停止。
サーブレットのインスタンスを1つにする
上のサンプルだと、リクエストのたびにサーブレットのインスタンスが生成されてしまいます。たとえば、次のようなサーブレットをマウントすると、
# サーブレットのIDを表示するサーブレット class IdServlet < HTTPServlet::AbstractServlet def do_GET(req, res) res['Content-Type'] = "text/html" res.body = "<html><body>id : #{__id__}</body></html>" end end
サーブレットにアクセスするたびに別のオブジェクトIDが出力されます。これを回避し、サーブレットインスタンスの生成タイミングを制御するには、サーブレットクラスに「get_instance」メソッドを定義します。(→Gnome's Guide to WEBrick - Controlling Servlet Instantiations)以下は、「get_instance」メソッドを定義して常に同じインスタンスを使うようにしたIdServletです。
# サーブレットのIDを表示するサーブレット class SingletonIdServlet < HTTPServlet::AbstractServlet # サーブレットの唯一のインスタンス @@instance = nil # インスタンス生成を同期化するためのMutex @@instance_creation_mutex = Mutex.new # サーブレットのインスタンスを生成するための関数 def self.get_instance(config, *options) @@instance_creation_mutex.synchronize { @@instance = self.new(config, *options) if @@instance == nil @@instance } end def do_GET(req, res) res['Content-Type'] = "text/html" res.body = "<html><body>id : #{__id__}</body></html>" end end
- クラスメソッドとして、「get_instance」を定義し、そこでインスタンスが未作成なら作成して返す処理を行っています。
- Mutexを使って同時に呼び出された場合にも複数のインスタンスを生成しないように制御しています。なるほどねー。
これをマウントしてアクセスすると、同じオブジェクトIDが出力されるようになります。