zeerd's blog         Search     Categories     Tags     Feed

闲来生雅趣,无事乐逍遥。对窗相望雪,一盏茶香飘。

使用NanoHttpd实现简易WebServer

#NanoHttpd #WebServer @Android


Contents:
NanoHTTPD是一个基于Java的简易Webserver实现,使用BSD授权。

我们可以在Android程序中通过NanoHTTPD实现一个简易的WebServer来达成某些需要——比如期望实现一个DLNA的DMS,正如WireMe中所做的那样。

这里,我将会给出来一个简单的例子实现。

首先,我们要实现一个继承于NanoHTTPD的WebServer Class。

假设我们的网页文件要存储在assets目录下,因此我需要一个AssetManager类成员变量来存储指针。

public class SimpleServer extends NanoHTTPD {
AssetManager asset_mgr;

public SimpleServer() {
// 端口是8088,也就是说要通过http://127.0.0.1:8088来访当问
super(8088);
}

public Response serve(String uri, Method method,
Map<String, String> header,
Map<String, String> parameters,
Map<String, String> files)
{
int len = 0;
byte[] buffer = null;

// 默认传入的url是以“/”开头的,需要删除掉,否则就变成了绝对路径
String file_name = uri.substring(1);

// 默认的页面名称设定为index.html
if(file_name.equalsIgnoreCase("")){
file_name = "index.html";
}

try {

//通过AssetManager直接打开文件进行读取操作
InputStream in = asset_mgr.open(file_name, AssetManager.ACCESS_BUFFER);

//假设单个网页文件大小的上限是1MB
buffer = new byte[1024*1024];

int temp=0;
while((temp=in.read())!=-1){
buffer[len]=(byte)temp;
len++;
}
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// 将读取到的文件内容返回给浏览器
return new NanoHTTPD.Response(new String(buffer,0,len));

}
}


接下来,我们要在MainActivity中启动这个WebServer。

public class MainActivity extends Activity {

private SimpleServer server;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

server = new SimpleServer();
try {

// 因为程序模拟的是html放置在asset目录下,
// 所以在这里存储一下AssetManager的指针。
server.asset_mgr = this.getAssets();

// 启动web服务
server.start();

Log.i("Httpd", "The server started.");
} catch(IOException ioe) {
Log.w("Httpd", "The server could not start.");
}
}

@Override
public void onDestroy()
{
super.onDestroy();

if (server != null){
// 在程序退出时关闭web服务器
server.stop();
}
Log.w("Httpd", "The server stopped.");
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

}


还有最重要的一件事情,权限:

<uses-permission android:name="android.permission.INTERNET"/>


剩下的工作就是从NanoHTTPD的网站上下载NanoHTTPD.java文件放入到Android工程的src目录下,并且编译调试它。

附带一个完整的工程包以供参考(好吧,它不太完整,我删除了libs目录)
emneg.zeerd.webserver