Java標準の組み込みWebサーバをApache Groovyで利用する
本記事はG* Advent Calendar 2017の18日目の記事です。
@tyamaさんのブログで紹介されていた、@glaforgeさんのこのツイートで初めて、Javaに組み込みWebサーバが存在していることを知りました!
ツイート内のコードだとシングルスレッド(HttpServer#start()を実行したスレッド)で全てのアクセスが同期して処理されるらしいので、事前にExecutorを定義してHttpServer#setExecutor()
で渡してあげてマルチスレッドでWebサーバを動かすようにしてみました。
import com.sun.net.httpserver.HttpServer import com.sun.net.httpserver.HttpExchange import java.util.concurrent.Executor class DirectExecutor implements Executor { public void execute(Runnable r) { // r.run() <--- これを実行すると同期処理にすることも出来る。 new Thread(r).start() } } HttpServer.create(new InetSocketAddress(8081), 0).with { createContext("/hello") { HttpExchange http -> println """ request method: ${http.requestMethod} protocol: ${http.protocol} remoteAddress: ${http.remoteAddress} headers: ${http.requestHeaders} URI: ${http.requestURI} body: ${http.requestBody} """ http.responseHeaders.add("Content-type", "text/plain") http.sendResponseHeaders(200, 0) http.responseBody.withWriter {out -> out << "Hello ${http.remoteAddress.hostName}" } } executor = new DirectExecutor() start() }
コレを適当なファイル名で保存しておいて、groovyコマンドで実行するだけでWebサーバの完成です。
これで、
curl -X POST http://localhost:8081/hello?a=b --data "hoge" --data "{a:b, c:d}"
というリクエストを投げると、コンソールには
request method: POST protocol: HTTP/1.1 remoteAddress: /127.0.0.1:42410 headers: [Accept:[*/*], Host:[localhost:8081], User-agent:[curl/7.35.0], Content-type:[application/x-www-form-urlencoded], Content-length:[15]] URI: /hello?a=b body: hoge&{a:b, c:d}
と出力されます。
ちょっとしたツールとかサービスなんかは、古き良き時代(?)のPHPスクリプトのように、Webサーバに結びついていてPHPスクリプトをその場で修正すれば即反映される、というような気軽な感じで作りたいという欲求が合ったので、すでに今回のG* Advent Calendar 2017で投稿したGroovyだけでWebサーバを実装する方法を応用すれば、このJava組み込みWebサーバでGroovyスクリプトを動かせるな〜とちょっとワクワクしています。