NanoHTTPD 是一个免费、轻量级的 (只有一个 Java 文件) HTTP 服务器,可以很好地嵌入到 Java 程序中。它支持 GET、POST、PUT、HEAD 和 DELETE 请求,支持文件上传,占用内存很小。
1 NanoHTTPD 的特点如下:
2 NanoHTTPD 的应用场景非常广泛,例如:
3 NanoHTTPD 的使用方法非常简单,只需以下几步即可:
?
<?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>
?
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");
}
}
?
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页面内容和执行指定路径的命令。?
?
放在服务器上 java -jar simpleWeb-1.0.jar就可以运行了。?
java -jar simpleWeb-1.0.jar
?运行成功,如下图:?
?
? ?NanoHTTPD 免费,轻量,开源 的特性是每个开发者的最爱,由于采用的是java,天生跨平台,所以还可以运行android手机上。