Javaで1ファイルで実装されたNanoHTTPDを触ってみた。
Apacheみたいなのが起動するんじゃなくて、自分のプロセスにwebサーバーの機能を埋め込むタイプ。

NanoHTTPD
https://github.com/elonen/nanohttpd


Androidで動かしている例も検索するとそれなりに出てくる。すんなり動くらしい。
Android上でWeb serverを動かしてみた – komamitsu.log
Androidアプリ開発に挑戦: Android で NanoHTTPD を使ってみる


とりあえずMacで試した。Androidではまだ試してない。
手元のファイルをHTTPで配信もできるし、リクエストのパスやメソッドやプロパティを読むことも出来る。
Androidのプログラムに埋め込めば、パソコンのwebブラウザからAndroidにアクセスして遠隔操作できて便利だと思う。


使い方

ドキュメントが無いけど実装がシンプルなのでgithubの本体のコードを見た。
new NanoHTTPD(8080, File(“.”));するだけで8080番で現在のディレクトリをdocument rootにしたhttpdが起動する。

カスタムするにはサンプルと同じくNanoHTTPDクラスを継承して、関数を自分で上書きしてしまえばいい。
主にserve(String uri, String method, Properties header, Properties parms, Properties files)を上書きする事になると思う。

本体のコードを見るとserveからserveFile関数を呼び出しているので、自分でserve関数を定義し直したらそこからfileServeも呼び出しなおしてあげないとファイル配信できなくなる。
(同梱されていたサンプルのHelloServer.javaではfileServeが動いていない)


webブラウザからMacを遠隔操作する例



サンプルのHelloServer.javaを改造してみた。特定のパス(/goと/stop)にリクエストが来たらMacのsayコマンドで「ゴー」「ストップ」と喋らせる。
それ以外のパスへのリクエストは、dataディレクトリ内のファイルを返すようにしてみた。
Androidのプログラムに埋め込む時は、SDカードやassetsのディレクトリでファイル配信すればいいと思う。
import java.io.*;
import java.util.*;

public class HelloServer extends NanoHTTPD
{
public HelloServer() throws IOException
{
super(8080, null);
}

public Response serve( String uri, String method, Properties header, Properties parms, Properties files )
{
System.out.println( method + " '" + uri + "' " );
if(uri.equals("/go")){
try{
Runtime.getRuntime().exec("/usr/bin/say go");
}catch(java.io.IOException e){
System.err.println(e);
}
System.out.println("go!!!!");
return new NanoHTTPD.Response( HTTP_OK, MIME_HTML, "go");
}
if(uri.equals("/stop")){
try{
Runtime.getRuntime().exec("/usr/bin/say stop");
}catch(java.io.IOException e){
System.err.println(e);
}
System.out.println("stop!!!!");
return new NanoHTTPD.Response( HTTP_OK, MIME_HTML, "stop");
}
return serveFile(uri, header, new File("./data"), true);
}


public static void main( String[] args )
{
try
{
new HelloServer();
}
catch( IOException ioe )
{
System.err.println( "Couldn't start server:" + ioe );
System.exit( -1 );
}
System.out.println( "Listening on port 8080. Hit Enter to stop." );
try { System.in.read(); } catch( Throwable t ) {};
}
}


dataというディレクトリを作ってその中にindex.htmlとして保存する。
ボタンが2つ並んでるだけだけど、押したらMacが「ゴー」「ストップ」とか喋る。
<html>
<head>
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js' type='text/javascript'></script>
<script type="text/javascript">
$(function(){
console.log("start");

$("#go").click(function(){
console.log("go button");
$.get("/go");
});
$("#stop").click(function(){
console.log("stop button");
$.get("/stop");
});

});
</script>
</head>
<body>
<h1>remote controll</h1>
<div>
<input type="button" value="go" id="go"></input>
<input type="button" value="stop" id="stop"></input>
</div>
</body>
</html>