一个非常小的http服务器NanoHTTPD使用教程

发布时间:2024年01月06日

?一 NanoHTTPD服务器介绍

NanoHTTPD 是一个免费、轻量级的 (只有一个 Java 文件) HTTP 服务器,可以很好地嵌入到 Java 程序中。它支持 GET、POST、PUT、HEAD 和 DELETE 请求,支持文件上传,占用内存很小。

1 NanoHTTPD 的特点如下:

  • 轻量级:只有一个 Java 文件,大小约为 30 KB。
  • 易用性:使用简单,只需几行代码即可启动一个 HTTP 服务器。
  • 灵活性:支持自定义请求处理逻辑。

2 NanoHTTPD 的应用场景非常广泛,例如:

  • 在嵌入式设备中提供简单的 HTTP 服务。
  • 在 Java 程序中开发本地代理服务器。
  • 在 Java 程序中开发简单的 Web 服务。

3 NanoHTTPD 的使用方法非常简单,只需以下几步即可:

  • 下载 NanoHTTPD 的源码或 JAR 包。
  • 在 Java 程序中导入 NanoHTTPD 的依赖项。
  • 创建一个 NanoHTTPD 实例。
  • 设置 NanoHTTPD 的端口和其他配置项。
  • 调用 NanoHTTPD 的 start() 方法启动服务器。

?

二?NanoHTTPD服务器开发使用?

? ?1,pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>simpleWeb</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.nanohttpd</groupId>
            <artifactId>nanohttpd</artifactId>
            <version>2.2.0</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.html</include>
                    <include>**/*.js</include>

                </includes>
            </resource>
        </resources>


        <plugins>
            <!-- Maven Assembly Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.java.WebService</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

    </build>



</project>

? ?2,http服务实现代码

?

  • 示例1 官方最简洁的启动示例代码:
import fi.iki.elonen.NanoHTTPD;

public class NanoHttpdExample {

    public static void main(String[] args) throws Exception {
        NanoHTTPD server = new NanoHTTPD(8080);
        server.start();

        System.out.println("HTTP 服务器已启动,端口:8080");
    }
}

?

  • 示例2 根据实际业务定制自己的服务器:
package com.java;

import fi.iki.elonen.NanoHTTPD;

import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

public class WebService extends NanoHTTPD {

    public WebService(int port) throws IOException {
        super(port);
        start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
        System.out.println("\nRunning! Point your browsers to http://localhost:" + port + "/ \n");
    }

    public static void main(String[] args) throws IOException {
        new WebService(13999);
    }

    @Override
    public Response serve(IHTTPSession session) {

        Method method = session.getMethod();
        String uri = session.getUri();
        String ip = session.getHeaders().get("http-client-ip");
        System.out.println(ip + " [" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "] >>> " + uri + "  ===> " + method);
        String html;
        String mimetype = "text/html";
        if (uri.endsWith(".html") || uri.endsWith(".htm")) {
            mimetype = "text/html";
        } else if (uri.endsWith(".js")) {
            mimetype = "text/javascript";
        } else if (uri.endsWith(".css")) {
            mimetype = "text/css";
        } else if (uri.endsWith(".ico")) {
            return newFixedLengthResponse("ico 404");

        } else {
            return handler(session);
            //uri = "index.html";
            //mimetype = "text/html";
        }


        //Map param = session.getParms();
        //System.out.println("param > " + param);
        //html = readHtml("/static/serList.html");
        //return newFixedLengthResponse(html);
        html = readHtml(uri);
        return newFixedLengthResponse(Response.Status.OK, mimetype, html);

    }


    private Response handler(IHTTPSession session) {
        if ("/exec".equals(session.getUri())) {
            Map param = session.getParms();
            if (param != null) {
                if (param.get("path") != null && param.get("authCode") != null) {
                    String r = exec((String) param.get("path"), (String) param.get("authCode"));
                    return newFixedLengthResponse(r);
                } else {
                    return newFixedLengthResponse("授权码不可为空!!!");
                }
            }
        }

        return newFixedLengthResponse("404!!");
    }

    public String exec(String path, String authCode) {

        String result;
        if ("passwd".equals(authCode)) {
            System.out.println("exec > " + path);


            String fullPath = "";
            if ("api".equals(path)) {
                fullPath = "/home/server/run_api";
            } else if ("api_upload".equals(path)) {
                fullPath = "/home/server/run_upload";
            } else if ("backend".equals(path)) {
                fullPath = "/home/server/run_backend";
            }else {
                return "操作失败,未知服务!!!";
            }

            System.out.println(path + " ====> " + fullPath);
            try {

                Runtime.getRuntime().exec(new String[]{"/bin/bash", fullPath});
                result = "exec ok";
            } catch (Exception e) {

                System.err.println(e.getMessage());
                result = "exec fail > " + e.getMessage();
            }
        } else {
            result = "authCode err!!!";
        }

        return result;
    }


    private String readHtml(String pathname) {
        BufferedReader br = null;
        StringBuffer sb = new StringBuffer();
        try {

            br = new BufferedReader(new InputStreamReader(WebService.class.getResourceAsStream(pathname), "UTF-8"));
            String temp = null;
            while ((temp = br.readLine()) != null) {
                sb.append(temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return "404 !!!";
        } catch (IOException e) {
            e.printStackTrace();
            return "Missing operating system!";
        }
        return sb.toString();
    }

}



?

说明:基于NanoHTTPD库就可以实现一个非常简单的Web服务类。它继承自NanoHTTPD类,并重写了serve方法来处理HTTP请求。根据请求的URI和方法,它返回不同的HTML页面或JavaScript/CSS资源。还提供了一个handler方法来处理特定的URI请求,例如执行指定路径的命令。执行结果会返回给客户端。整个类还提供了一些辅助方法,例如读取HTML页面内容和执行指定路径的命令。?

? 3,编译jar放在服务器上运行。

?

放在服务器上 java -jar simpleWeb-1.0.jar就可以运行了。?

java -jar simpleWeb-1.0.jar

?运行成功,如下图:?

?

三 总结?

? ?NanoHTTPD 免费,轻量,开源 的特性是每个开发者的最爱,由于采用的是java,天生跨平台,所以还可以运行android手机上。

文章来源:https://blog.csdn.net/qyhua/article/details/135414090
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。