Android设备一般是作为客户端使用,但是最近一个项目需要用android开发板作为服务器和手机端通信,因此花了点时间研究了下如何在android上运行http server。

实际上这是有开源解决方案的,叫做AndroidAsync,作者是Koushik Dutta,他的另一个开源项目是大名鼎鼎的ION,这是一个异步网络图片加载库。但是AndroidAsync几乎没什么文档,因此实际使用中遇到了一些问题,记录下了方便其他有需要的人参考。

AndroidAsync中提供了一个AsyncHttpServer类处理网络请求,而我们需要实现HttpServerRequestCallback接口执行实际的业务逻辑,实际上该接口只有一个onRequest()方法。首先我们要为GET/POST方法注册callback,然后开始监听端口:

public class ArtemisHttpServer implements HttpServerRequestCallback {    public static int PORT_DEFALT = 6789;    AsyncHttpServer mServer = new AsyncHttpServer();    public void start() {        Log.d(TAG, "Starting http server...");        mServer.get("[\\d\\D]*", this);        mServer.post("[\\d\\D]*", this);        mServer.listen(PORT_DEFALT);    }    public void stop() {        Log.d(TAG, "Stopping http server...");        mServer.stop();    }}

实际使用时一般使用单例模式,代码这里略去了。接下来就是实现onRequest()方法了:

  • 获取请求路径:通过request.getPath()
  • 获取GET参数:通过request.getQuery()
  • 获取POST参数:这个比较麻烦,github上也没有任何参考,经研究发现:
    • Form格式:需要把body转换成AsyncHttpRequestBody
    • JSON格式:需要把body转换成AsyncHttpRequestBody
@Overridepublic void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {    String uri = request.getPath();    Log.d(TAG, "onRequest " + uri);    Object params;    if (request.getMethod().equals("GET")) {        params = request.getQuery();    } else if (request.getMethod().equals("POST")) {        String contentType = request.getHeaders().get("Content-Type");        if (contentType.equals("application/json")) {            params = ((AsyncHttpRequestBody) request.getBody()).get();        } else {            params = ((AsyncHttpRequestBody) request.getBody()).get();        }    } else {        Log.d(TAG,"Unsupported Method");        return;    }    if (params != null) {        Log.d(TAG, "params = " + params.toString());    }    switch (uri) {        case "/devices":            handleDevicesRequest(params, response);            break;        default:            handleInvalidRequest(params, response);            break;    }}

得到的参数对象为Multimap或者JSONObject类型,接下来调用getString()就可以获取具体的参数值了:

String id = "";if (params instanceof Multimap) {    id = ((Multimap) params).getString("id");    Log.d(TAG, "[Multimap] id=" + id);} else if (params instanceof JSONObject) {    try {        Log.d(TAG, params.toString());        id = ((JSONObject) params).getString("id");    } catch (JSONException e) {        e.printStackTrace();        return;    }    Log.d(TAG, "[JSONObject] id=" + id);} else {    Log.e(TAG, "Invalid request params");    return;}

后面就是根据path调用对应的API进行处理,然后通过response对象发送响应。如果要支持跨域,可以在response的header中增加字段:

private void sendResponse(AsyncHttpServerResponse response, JSONObject json) {    // Enable CORS    response.getHeaders().add("Access-Control-Allow-Origin", "*");    response.send(json);}

完整示例代码参见github:https://github.com/qianxin2016/AndroidHttpServer

更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
或关注飞久微信公众号:

更多相关文章

  1. android 7种网络连接方式《IT蓝豹》
  2. Android深入浅出之Zygote[1]
  3. android 基于百度地图api开发定位以及获取详细地址
  4. android瀑布流简单实现原理
  5. 【Android(安卓)Demo】通过WebService获取今日天气情况
  6. Android(安卓)之采用execSQL和rawQuery方法完成数据的添删改查操
  7. mybatisplus的坑 insert标签insert into select无参数问题的解决
  8. Python技巧匿名函数、回调函数和高阶函数
  9. python list.sort()根据多个关键字排序的方法实现

随机推荐

  1. Android实现自动定位城市并获取天气信息
  2. android 按纽状态配置文件
  3. android之获得当前连接wifi的名字
  4. android获取屏幕长宽的方法
  5. Android:setLatestEventInfo问题
  6. android语音识别之科大讯飞语音API的使用
  7. Android(安卓)Socket编程
  8. Android(安卓)实现开机自启动 Service
  9. Android(安卓)ble setCharactersticNotif
  10. android WebView结合javascript相互调用