Androidシステムにwebserviceを導入

4209 ワード

1.前期技術選択型
Androidシステムでサーバーを作るのは、本当にやる人が少ないと信じています.検索の結果、私が最初に見つけたのはi-jettyです.これはjettyがクロスコンパイルを経てandroidプラットフォームに移植したwebサーバソフトウェアで、webサイトを配置することができます.しかし、これは私が望んでいるものではありません.第一に、それは大きすぎて、第二に、二次開発は難しいです.だから私は簡単な方法を探し続けました.まず私が思いついたのはjavaを使ってhttpプロトコルに従って1つ開発することでしょう、そこで1つの小型のgetを書いて、post要求のサーバー、しかしレベルの原因のため、大量のバグが存在します.これは私の方向が基本的に確定して、私が必要とするのはandroidで実行するサーバーだけではなくて、純粋なjava環境でサービスすることができます.やっと、stack overflowでこの問題の解を見つけました.NanoHttpd、上の人はvery simpleと答えました.最初の直感はこれが私に必要です.
2.NanoHttpdについて
NanoHTTPD gitHubアドレス:https://github.com/NanoHttpd/nanohttpd readmeファイルを読むことで、これは開発プロジェクトがmavenを使って管理され、coreの中でNanoHTTPD.javaがこのプロジェクトの核心であり、only one file.は素晴らしいです.そこで私はgithubからソースコードを引き、ローカルではmavenを使用しないため、NanoHTTPD.javaファイルとそのexampleフォルダをコピーしただけです.HelloServerを実行してブラウザでアクセスしたら、やはり成功しました.
package fi.iki.elonen;

import java.util.Map;
import java.util.logging.Logger;

import fi.iki.elonen.util.ServerRunner;

/**
 * An example of subclassing NanoHTTPD to make a custom HTTP server.
 */
public class HelloServer extends NanoHTTPD {

    /**
     * logger to log to.
     */
    private static final Logger LOG = Logger.getLogger(HelloServer.class.getName());

    public static void main(String[] args) {
        ServerRunner.run(HelloServer.class);
    }

    public HelloServer() {
        super(8080);
    }

    @Override
    public Response serve(IHTTPSession session) {
        Method method = session.getMethod();
        String uri = session.getUri();
        HelloServer.LOG.info(method + " '" + uri + "' ");

        String msg = "

Hello server


"; Map parms = session.getParms(); if (parms.get("username") == null) { msg += "

" + "

Your name:


" + "

"; } else { msg += "

Hello, " + parms.get("username") + "!

"; } msg += "
"; return newFixedLengthResponse(msg); } }

HelloServerクラスを見ると、独自のwebserviceを実現するには、NanoHTTPDを継承し、serveメソッドを書き換えるだけでよいことがわかります.IHTTPSessionにはリクエストのすべてが含まれており、sessionを処理してResponseに戻るだけでいいです.
3.独自のhttpサーバの作成を開始
私のニーズに応じて、主にgetとpostリクエストを実現するためです.
1.getリクエスト
getリクエストの内容はurlに直接、postリクエストの内容は本文にあります.一般的にgetがurlのフォーマットを要求するのは、http://localhost:80/webservice?username=lilei&password=12345 urlから必要な情報を抽出します.もちろん、車輪を繰り返す必要はありません.NanoHttpdは私たちに書いてくれました.私たちは1行のコードMap parms = session.getParms();で必要な内容を得ることができます.
2.postリクエストMethod method = session.getMethod();によって要求を取得する方法であり、Methodは列挙変数である.まずsessionが本文の内容を取得できないのではないかと疑問に思っています.session.getinputstreamだけができます.これはちょっと面倒だ.そこでNanoHttpdのソースコードを読み、ソースコードにbody処理の方法があることを発見しました.
    Map files = new HashMap();
    try {
            session.parseBody(files);
        } catch (IOException ioe) {
            return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, NanoHTTPD.MIME_PLAINTEXT, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
        } catch (ResponseException re) {
            return newFixedLengthResponse(re.getStatus(), NanoHTTPD.MIME_PLAINTEXT, re.getMessage());
        }
        String parameter =  files.get("postData");
        System.out.println(parameter);

postDataを取り出すだけで、String parameter = files.get("postData");は私たちが必要とする本文です.(jsonを用いてデータ転送を行います).これにより、カスタマイズされたwebserverは、依存パッケージにパッケージ化し、androidプロジェクトに追加し、起動するだけで、外部からアクセスし、androidデバイスを制御することができます.
4.問題と拡張
私はソースコードの中に多くのテストコードがあるのを見て、コアに問題はないと信じていますが、実際に実行している間に、私はまた1つの問題を発見しました.しかし、ローカルにアクセスしないときは、速度が非常に遅く、基本的に10.26 sぐらいです.この10 sはタイムアウトの時やどこかで睡眠をとる時間でしょう.Debugを経て、NanoHttpdで憎らしい行のコードを見つけました.inetAddress.getHostName().toString();この行のコードはクライアントホスト名を逆方向に検索し、ローカルにこのホスト名とipのマッピングがなければ、かなり遅いです.だから私はためらうことなくこのコードを注釈しました.△あとでチームがどう思っているか聞いてみなければなりません.
拡張:urlリクエストを異なるクラス処理に配布し、これらのクラスは共通してactionインタフェースを実現します.絶えず追加する異なる処理の必要性を便利にします.私は小さなフレームワークを実現しました.次の節で話します.