博客
关于我
使用NanoHttpd在Android项目中搭建服务器
阅读量:801 次
发布时间:2019-03-25

本文共 5982 字,大约阅读时间需要 19 分钟。

小型HTTP服务器NanoHTTPD的配置与使用

作为一名开发人员,如果你需要快速搭建一个轻量级的HTTP服务器,NanoHTTPD是一个非常不错的选择。它不仅支持常见的HTTP方法(如GET、POST、PUT、HEAD和DELETE),还能方便地嵌入到Java程序中,同时占用内存非常小。这意味着它非常适合开发需要一个简单服务器来处理文件上传或API请求的项目。

为什么选择NanoHTTPD?

NanoHTTPD的优势在于:

  • 超轻量:仅需要一个Java文件即可运行,无需外部依赖。
  • 功能全面:支持多种HTTP方法和文件上传。
  • 易于嵌入:可以直接在Java程序中使用,完全按照你的需求定制。

接下来,我将指导你如何在项目中集成NanoHTTPD,并通过代码示例展示如何使用它来快速搭建一个文件服务器。


快速上手指南

1. 添加依赖

如果你不想直接从GitHub下载,可以在项目的build.gradle文件中添加依赖。我假设你项目结构如下:

your-project/├── build.gradle└── src/    └── main/        └── java/            └── YourPackage/                └── YourServer.java

build.gradle中添加以下依赖:

dependencies {    implementation 'org.nanohttpd:nanohttpd:2.2.0'}

2. 创建文件服务器

假设你想在项目中创建一个简单的文件服务器。那我们就从YourPackage包下创建一个继承自NanoHTTPDFileServer类。

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;public class FileServer extends NanoHTTPD {    private static final int DEFAULT_PORT = 8080;    private static final String TAG = "FileServer";    private List
fileList; // constructor public FileServer(List
fileList) { super(DEFAULT_PORT); this.fileList = fileList; } // 掏个小窍门:_MAGIC_TAG_ 这里是你的独特标签 private static final String REQUEST_ROOT = "/"; @Override public Response serve(IHTTPSession session) { String uri = session.getUri(); if (uri.equals(REQUEST_ROOT) || uri.isEmpty()) { return responseRootPage(session); } else { return responseFile(session); } } private Response responseRootPage(IHTTPSession session) { StringBuilder builder = new StringBuilder(); builder.append(""); // 开始生成HTML builder.append("
File List"); builder.append(""); for (File file : fileList) { if (file.exists()) { builder.append("
"); builder.append("
"); builder.append(file.getName()); builder.append(""); builder.append("
"); } } builder.append(""); return Response.newFixedLengthResponse(builder.toString()); } private Response responseFile(IHTTPSession session) { try { 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(); } // 遇到未找到的文件,返回404 return response404(session, uri); } private Response response404(IHTTPSession session, String url) { StringBuilder builder = new StringBuilder(); builder.append("
404 - File Not Found"); builder.append("

Sorry, Can't Found

"); builder.append("

\"" + url + "\" Undefined!

"); builder.append(""); return Response.newFixedLengthResponse(builder.toString()); }}

3. 启动服务器

创建一个服务类来启动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.List;import caro.automation.MyApplication;import caro.automation.DatabaseSelectUpload;public class HttpServer extends NanoHTTPD {    private static final String TAG = "HttpServer";    private static final int DEFAULT_PORT = 8080;    public HttpServer(int port) {        super(port);    }    @Override    public Response serve(IHTTPSession session) {        try {            // 根据自己的项目逻辑获取文件列表            // 这里暂时假设fileList是动态加载的,或者从数据库中获取            for (String file : DatabaseSelectUpload.name_) {                session.parseBody(new HashMap<>());                String filePath = MyApplication.GetApp().getExternalFilesDir(null) + "/你的文件路径";                // 获取完整的文件路径                File targetFile = new File(filePath + "/" + file + ".db3");                if (targetFile.exists()) {                    FileInputStream fis = new FileInputStream(targetFile);                    return Response.newFixedLengthResponse(Status.OK, "application/octet-stream",                            fis, fis.available());                }            }        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return response404(session, "/你的URL");    }    @Override    public Response response404(IHTTPSession session, String url) {        StringBuilder builder = new StringBuilder();        builder.append("404 - NotFound");        builder.append("

404 - File Not Found

"); builder.append("

\"" + url + "\" - File does not exist.

"); builder.append(""); return Response.newFixedLengthResponse(builder.toString()); } public static void main(String[] args) { // 在这里启动你需要的服务 // 比如:你可能需要修改为startService,而不仅仅是启动服务器 }}

4. 启动与关闭服务器

在需要的时候启动服务器,你可以在onCreate方法中启动,onDestroy方法中停止:

public class MyServer extends HttpServer {    public MyServer() {        super(DEFAULT_PORT);    }    @Override    public void onDestroy() {        super.stopService(new Intent(getApplicationContext(), MyServer.class));    }}

注意事项

  • 文件路径管理:确保文件路径是正确的,尤其是在不同操作系统上测试时。
  • 权限设置:服务器需要有权限访问所需文件,否则会抛出FileInfoException或类似的错误。
  • 缓存机制:如果你需要缓存 frequent请求,可以自定义缓存策略。
  • 安全性:根据需要添加用户认证或权限检查,防止未授权访问。

  • 通过以上配置,你可以轻松实现一个嵌入式的HTTP服务器,支持文件上传和下载。你可以根据实际需求定制FileServer类或扩展其功能,使其更符合项目需求。

    转载地址:http://yqyyk.baihongyu.com/

    你可能感兴趣的文章
    mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
    查看>>
    Multiple websites on single instance of IIS
    查看>>
    mysql CONCAT()函数拼接有NULL
    查看>>
    multiprocessing.Manager 嵌套共享对象不适用于队列
    查看>>
    multiprocessing.pool.map 和带有两个参数的函数
    查看>>
    MYSQL CONCAT函数
    查看>>
    multiprocessing.Pool:map_async 和 imap 有什么区别?
    查看>>
    MySQL Connector/Net 句柄泄露
    查看>>
    multiprocessor(中)
    查看>>
    mysql CPU使用率过高的一次处理经历
    查看>>
    Multisim中555定时器使用技巧
    查看>>
    MySQL CRUD 数据表基础操作实战
    查看>>
    multisim变压器反馈式_穿过隔离栅供电:认识隔离式直流/ 直流偏置电源
    查看>>
    mysql csv import meets charset
    查看>>
    multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
    查看>>
    MySQL DBA 数据库优化策略
    查看>>
    multi_index_container
    查看>>
    MySQL DBA 进阶知识详解
    查看>>
    Mura CMS processAsyncObject SQL注入漏洞复现(CVE-2024-32640)
    查看>>
    Mysql DBA 高级运维学习之路-DQL语句之select知识讲解
    查看>>