使用NanoHttpd在Android項目中搭建服務器

NanoHTTPD是一個免費、輕量級的(只有一個Java文件) HTTP服務器,可以很好地嵌入到Java程序中。支持 GET, POST, PUT, HEAD 和 DELETE 請求,支持文件上傳,佔用內存很小。

github地址:https://github.com/NanoHttpd/nanohttpd

下載完demo項目後,解壓,找到路徑,我的是放在F盤下:

F:\nanohttpd-master\core\src\main\java\org\nanohttpd

把整個nanohttpd文件夾複製到項目下即可使用了。

項目中的截圖如下:

如果比較懶不想去github下載的話,可以直接在build.gradle中添加依賴(我之前是不知道這個依賴,所以用的是下載的文件):

implementation'org.nanohttpd:nanohttpd:2.2.0'

 具體使用:

首先先寫一個類FileServer繼承nanohttpd:

package caro.automation.server;

import org.nanohttpd.protocols.http.IHTTPSession;
import org.nanohttpd.protocols.http.NanoHTTPD;
import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.protocols.http.response.Status;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

/**
 * Created by XDA on 2019/4/2.
 */
public class FileServer extends NanoHTTPD {
//    public static final int DEFAULT_SERVER_PORT= com.example.zjt.nanohttpexample.Status.MY_PORT;//爲8080
    public static final int DEFAULT_SERVER_PORT= 8080;//爲8080
    public static final String TAG = FileServer.class.getSimpleName();
    //根目錄
    private static  final String REQUEST_ROOT = "/";
    private List<SharedFile> fileList;//用於分享的文件列表

    public FileServer(List<SharedFile> fileList){
        super(DEFAULT_SERVER_PORT);
        this.fileList = fileList;
    }
    //當接受到連接時會調用此方法
    public Response serve(IHTTPSession session){
        if(REQUEST_ROOT.equals(session.getUri())||session.getUri().equals("")){
            return responseRootPage(session);
        }
        return responseFile(session);
    }
    //對於請求根目錄的,返回分享的文件列表
    public Response responseRootPage(IHTTPSession session){
        StringBuilder builder = new StringBuilder();
        builder.append("<!DOCTYPER html><html><body>");
        builder.append("<ol>");
        for(int i = 0 , len = fileList.size(); i < len ; i++){
            File file = new File(fileList.get(i).getPath());
            if(file.exists()){
                //文件及下載文件的鏈接,定義了一個文件類,這裏使用getPath方法獲得路徑,使用getName方法獲得文件名
                builder.append("<li> <a href=\""+file.getPath()+"\">"+file.getName()+"</a></li>");
            }
        }
        builder.append("<li>分享文件數量:  "+fileList.size()+"</li>");
        builder.append("</ol>");
        builder.append("</body></html>\n");
        //回送應答
        return Response.newFixedLengthResponse(String.valueOf(builder));
    }
    //對於請求文件的,返回下載的文件
    public Response responseFile(IHTTPSession session){
        try {
            //uri:用於標示文件資源的字符串,這裏即是文件路徑
            String uri = session.getUri();
            //文件輸入流
            FileInputStream fis = new FileInputStream(uri);
            // 返回OK,同時傳送文件,爲了安全這裏應該再加一個處理,即判斷這個文件是否是我們所分享的文件,避免客戶端訪問了其他個人文件
            return Response.newFixedLengthResponse(Status.OK,"application/octet-stream",fis,fis.available());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response404(session,null);
    }
    //頁面不存在,或者文件不存在時
    public Response response404(IHTTPSession session,String url) {
        StringBuilder builder = new StringBuilder();
        builder.append("<!DOCTYPE html><html>body>");
        builder.append("Sorry,Can't Found" + url + " !");
        builder.append("</body></html>\n");
        return Response.newFixedLengthResponse(builder.toString());
    }
}

然後創建一個服務類HttpServer來開啓FileServer:

package caro.automation.server;

import org.nanohttpd.protocols.http.IHTTPSession;
import org.nanohttpd.protocols.http.NanoHTTPD;
import org.nanohttpd.protocols.http.response.Response;
import org.nanohttpd.protocols.http.response.Status;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import caro.automation.MyApplication;
import caro.automation.modify.DatabaseSelectUpload;

/**
 * Created by XDA on 2019/3/25.
 */
public class HttpServer extends NanoHTTPD {
    private static final String TAG = "Http";
    public HttpServer(int port) {
        super(port);
    }






    @Override
    public Response serve(IHTTPSession session) {


            try {
                for (int i = 0; i < DatabaseSelectUpload.name_.size(); i++) {  //for 循環文件名 小於name的個數
                session.parseBody(new HashMap<String, String>());
                final String choose = DatabaseSelectUpload.name_.get(i);//獲取循環到的文件名
                String strDBPath = MyApplication.GetApp().getExternalFilesDir(null) + "/TIS-Smarthome/" + choose + "/" + (choose + ".db3");//數據庫地址

                    FileInputStream fis = new FileInputStream(strDBPath);

                    return Response.newFixedLengthResponse(Status.OK, "application/octet-stream", fis, fis.available());
                }

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ResponseException e) {
                e.printStackTrace();
            }

        return response404(session, null);
    }

    //頁面不存在,或者文件不存在時
    public Response response404(IHTTPSession session,String url) {
               StringBuilder builder = new StringBuilder();
        builder.append("<!DOCTYPE html><html>body>");
        builder.append("Sorry,Can't Found" + url + " !");
        builder.append("</body></html>\n");
        return Response.newFixedLengthResponse(builder.toString());
    }



}

ps: 

"application/octet-stream"

這個參數的意思是以流的形式下載文件,這樣可以實現任意格式的文件下載。

 

然後在需要開啓服務器的地方,例如在Activity的onCreate方法中開啓:

startService(new Intent(getApplicationContext(),MyServer.class));//開啓NanoHttpD 8080端口

記得在onDestroy方法中關閉服務器:

stopService(new Intent(getApplicationContext(),MyServer.class)); //關閉 NanoHTTPD   8080

我的是192.168.1.168:8080 打開後可以看到:

這裏顯示的就是頁面爲空的時候的顯示。response404()方法裏面寫好的顯示內容。

 

這樣就是成功開啓了服務器了。然後就可以根據這個url來上傳下載文件。

我這邊是使用的OKgo來上傳下載文件的。下一篇會介紹一下我自己寫的辣雞代碼。

簡單使用Okgo上傳下載文件,有興趣可以瞄一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章