是否有一种方法可以使用Java SE API在Java中创建一个非常基本的HTTP服务器(只支持GET/POST),而不需要编写代码手动解析HTTP请求和手动格式化HTTP响应?Java SE API在HttpURLConnection中很好地封装了HTTP客户机功能,但是是否有类似的HTTP服务器功能呢?
需要明确的是,我在网上看到的许多ServerSocket示例的问题是,它们自己进行请求解析/响应格式化和错误处理,这很乏味,容易出错,而且不太全面,出于这些原因,我试图避免使用它。
是否有一种方法可以使用Java SE API在Java中创建一个非常基本的HTTP服务器(只支持GET/POST),而不需要编写代码手动解析HTTP请求和手动格式化HTTP响应?Java SE API在HttpURLConnection中很好地封装了HTTP客户机功能,但是是否有类似的HTTP服务器功能呢?
需要明确的是,我在网上看到的许多ServerSocket示例的问题是,它们自己进行请求解析/响应格式化和错误处理,这很乏味,容易出错,而且不太全面,出于这些原因,我试图避免使用它。
当前回答
我喜欢这个问题,因为这是一个不断创新的领域,总是需要有一个轻型服务器,特别是当谈到小型设备中的嵌入式服务器时。我认为答案可以分为两大类。
瘦服务器:使用最少处理、上下文或会话处理的服务器式静态内容。 小型服务器:从表面上看,a具有许多类似httpd的服务器特性,并且占用的空间尽可能小。
虽然我可能会认为HTTP库,如:Jetty, Apache HTTP Components, Netty和其他更像一个原始的HTTP处理工具。标签是非常主观的,取决于你被要求为小网站提供的东西的种类。我是根据问题的精神,特别是关于……
"...无需编写代码手动解析HTTP请求和手动格式化HTTP响应……”
These raw tools let you do that (as described in other answers). They don't really lend themselves to a ready-set-go style of making a light, embedded or mini-server. A mini-server is something that can give you similar functionality to a full-function web server (like say, Tomcat) without bells and whistles, low volume, good performance 99% of the time. A thin-server seems closer to the original phrasing just a bit more than raw perhaps with a limited subset functionality, enough to make you look good 90% of the time. My idea of raw would be makes me look good 75% - 89% of the time without extra design and coding. I think if/when you reach the level of WAR files, we've left the "small" for bonsi servers that looks like everything a big server does smaller.
瘦服务器选项
灰熊 UniRest(多语言) NanoHTTPD(只有一个文件)
Mini-server选项:
Spark Java…有了很多帮助器结构,比如过滤器、模板等,就有可能做得很好。 MadVoc……目标是成为盆景,而且很可能是这样;-)
Among the other things to consider, I'd include authentication, validation, internationalisation, using something like FreeMaker or other template tool to render page output. Otherwise managing HTML editing and parameterisation is likely to make working with HTTP look like noughts-n-crosses. Naturally it all depends on how flexible you need to be. If it's a menu-driven FAX machine it can be very simple. The more interactions, the 'thicker' your framework needs to be. Good question, good luck!
其他回答
检查拍摄。查看https://github.com/yegor256/takes获取快速信息
Apache Commons HttpCore项目怎么样?
来自网站:…… HttpCore目标
实现最基本的HTTP传输方面 良好的表现和清晰的表达之间的平衡 API 小(可预测的)内存占用 自包含库(没有JRE以外的外部依赖)
检出简单。它是一个非常简单的嵌入式服务器,内置了对各种操作的支持。我特别喜欢它的线程模型..
神奇的!
从Java 18开始,你可以用Java标准库创建简单的web服务器:
class Main {
public static void main(String[] args) {
var port = 8000;
var rootDirectory = Path.of("C:/Users/Mahozad/Desktop/");
var outputLevel = OutputLevel.VERBOSE;
var server = SimpleFileServer.createFileServer(
new InetSocketAddress(port),
rootDirectory,
outputLevel
);
server.start();
}
}
默认情况下,这将显示指定根目录的目录列表。您可以将index.html文件(以及CSS和JS文件等其他资产)放在该目录中来显示它们。
示例(我把这些放在桌面上,上面指定为我的根目录):
index . html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Java 18 Simple Web Server</title>
<link rel="stylesheet" href="styles.css">
<style>h1 { color: blue; }</style>
<script src="scripts.js" defer>
let element = document.getElementsByTagName("h1")[0];
element.style.fontSize = "48px";
</script>
</head>
<body>
<h1>I'm <i>index.html</i> in the root directory.</h1>
</body>
</html>
旁注
对于Java标准库HTTP客户端,请参阅Java 11新HTTP客户端API。
httpserver解决方案不能跨jre移植。最好使用javax.xml.ws中的官方webservices API来引导一个最小的HTTP服务器…
import java.io._
import javax.xml.ws._
import javax.xml.ws.http._
import javax.xml.transform._
import javax.xml.transform.stream._
@WebServiceProvider
@ServiceMode(value=Service.Mode.PAYLOAD)
class P extends Provider[Source] {
def invoke(source: Source) = new StreamSource( new StringReader("<p>Hello There!</p>"));
}
val address = "http://127.0.0.1:8080/"
Endpoint.create(HTTPBinding.HTTP_BINDING, new P()).publish(address)
println("Service running at "+address)
println("Type [CTRL]+[C] to quit!")
Thread.sleep(Long.MaxValue)
编辑:这实际上是工作!上面的代码看起来像Groovy之类的。以下是我测试的Java翻译:
import java.io.*;
import javax.xml.ws.*;
import javax.xml.ws.http.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
@WebServiceProvider
@ServiceMode(value = Service.Mode.PAYLOAD)
public class Server implements Provider<Source> {
public Source invoke(Source request) {
return new StreamSource(new StringReader("<p>Hello There!</p>"));
}
public static void main(String[] args) throws InterruptedException {
String address = "http://127.0.0.1:8080/";
Endpoint.create(HTTPBinding.HTTP_BINDING, new Server()).publish(address);
System.out.println("Service running at " + address);
System.out.println("Type [CTRL]+[C] to quit!");
Thread.sleep(Long.MAX_VALUE);
}
}