43

Android上运行Http Server

 5 years ago
source link: https://blog.csdn.net/TurkeyCock/article/details/86555919?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TurkeyCock/article/details/86555919

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<Multimap>
    • JSON格式:需要把body转换成AsyncHttpRequestBody<JSONObject>
@Override
public 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<JSONObject>) request.getBody()).get();
        } else {
            params = ((AsyncHttpRequestBody<Multimap>) 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

或关注飞久微信公众号: qMriYz7.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK