MiniServer
Sun Java SDK 1.6から,HttpServerを用いれば簡易的なWebサーバを簡単に構築できるようになった.
ここでは,以下の機能を持つWebサーバのサーバープログラムを作成してみる.
- リクエストのパスが /html/xx/yy/zz.html なら,指定したドキュメントルート以下の/xx/yy/zz.html のファイルの内容を返す.
- MIME typeには対応していない.
- リクエストのパスが /command/xx?p1=a1&p2=a2 なら,JSONオブジェクトとして{p1:a1, p2,a2} を返す.ただし xx は quit 以外.
- 文字列のデコードは行っていない.
- リクエストのパスが /command/quit ならサーバーを終了する.
MiniServer.java
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import org.json.JSONException; import org.json.JSONObject; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class MiniServer { public int port = 8080; public String documentRoot = null; public String htmlPath = "/html"; public String commandPath = "/command"; public boolean quit = false; public MiniServer(int port, String documentRoot) throws IOException { this.port = port; this.documentRoot = documentRoot; if (documentRoot == null) { throw new IOException("Document documentRoot is not specified"); } } public synchronized void quit() { quit = true; notifyAll(); } public class HtmlHandler implements HttpHandler { int buffSize = 1024; File dir; public HtmlHandler(File dir) { this.dir = dir; } public void handle(HttpExchange exchange) throws IOException { String path0 = exchange.getHttpContext().getPath(); String path1 = exchange.getRequestURI().getPath(); String path = documentRoot + path1.substring(path0.length()); int code = 0; OutputStream out = exchange.getResponseBody(); File file = new File(path); try { if (file.isFile()) { InputStream in = new FileInputStream(file); code = 200; exchange.sendResponseHeaders(code, 0); byte[] buff = new byte[buffSize]; while (in.available() > 0) { int length = in.read(buff); out.write(buff, 0, length); } in.close(); } } catch (IOException e) { } if (code == 0) { code = 404; String msg = "<h1>" + code + " Not Found</h1>"; msg += exchange.getRequestURI(); exchange.sendResponseHeaders(code, 0); out.write(msg.getBytes()); } out.close(); } } public class CommandHandler implements HttpHandler { public synchronized void handle(HttpExchange exchange) throws IOException { String path0 = exchange.getHttpContext().getPath(); String path1 = exchange.getRequestURI().getPath(); String path = path1.substring(path0.length()); String query = exchange.getRequestURI().getRawQuery(); OutputStream out = exchange.getResponseBody(); String str = null; try { if (path.equals("/quit")) { quit(); str = ""; } else if (path.equals("/query")) { JSONObject json = new JSONObject(); for (String q : query.split("&")) { String[] s = q.split("=", 2); json.put(s[0], s[1]); } str = json.toString(); } } catch (JSONException e) { } int code = 200; if (str == null) { code = 404; str = code + " Not Found " + exchange.getRequestURI(); } exchange.sendResponseHeaders(code, 0); out.write(str.getBytes()); out.close(); } } public synchronized void start() throws IOException { HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); File dir = new File(documentRoot); if (dir.isDirectory()) { server.createContext(htmlPath, new HtmlHandler(dir)); } server.createContext(commandPath, new CommandHandler()); server.start(); System.out.println("MiniTrace server starting on port " + port); quit = false; while (! quit) { try { wait(); } catch (InterruptedException e) { } } server.stop(0); System.out.println("MiniTrace server stopped"); } public static void main(String[] args) { int port = 8080; String documentRoot = null; try { int i = 0; while (i < args.length) { if (args[i].equals("-port") && i + 1 < args.length) { i++; port = Integer.parseInt(args[i]); } else if (args[i].equals("-html") && i + 1 < args.length) { i++; documentRoot = args[i]; } i++; } MiniServer miniServer = new MiniServer(port, documentRoot); miniServer.start(); } catch (IOException e) { e.printStackTrace(); } } }