仅使用 Java SE API 的 Java 简单 HTTP 服务器
有没有一种方法可以仅使用 Java SE API 在 Java 中创建一个非常基本的 HTTP 服务器(仅支持 GET/POST),而无需编写代码来手动解析 HTTP 请求并手动格式化 HTTP 响应? Java SE API 很好地将 HTTP 客户端功能封装在 HttpURLConnection
中,但是是否有类似的 HTTP 服务器功能呢?
需要明确的是,我在网上看到的许多 ServerSocket
示例的问题是它们自己进行请求解析/响应格式化和错误处理,这是乏味的,容易出错的,而且不太可能全面,出于这些原因我试图避免它。
Is there a way to create a very basic HTTP server (supporting only GET/POST) in Java using just the Java SE API, without writing code to manually parse HTTP requests and manually format HTTP responses? The Java SE API nicely encapsulates the HTTP client functionality in HttpURLConnection
, but is there an analog for HTTP server functionality?
Just to be clear, the problem I have with a lot of ServerSocket
examples I've seen online is that they do their own request parsing/response formatting and error handling, which is tedious, error-prone, and not likely to be comprehensive, and I'm trying to avoid it for those reasons.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
这是我的简单网络服务器,在 JMeter 中用于测试网络钩子(这就是为什么它会在收到请求后自行关闭并结束)。
你可以这样测试:
Here is my simple webserver, used in JMeter for testing webhooks (that's why it will close and end itself after request is received).
You can test it like this:
我玩得很开心,我把玩了一下并将其拼凑在一起。我希望它对你有帮助。
您将需要安装 Gradle 或使用带有插件的 Maven。
build.gradle
FooServer
主要入口点,您的主类。
运行它:
浏览到:
I had some fun, I toyed around and pieced together this. I hope it helps you.
You are going to need Gradle installed or use Maven with a plugin.
build.gradle
FooServer
The main entry point, your main class.
Run it:
Browse to:
您的问题有一个非常好的答案库,涵盖仅使用 Java SE 的创建 Web 服务器。然而,有些人可能会对 Android 平台上运行的类似解决方案感兴趣。它很自然地限制为 Java SE,甚至最大 JVM 版本也可以限制为 Java 8。我使用 Atjeews 在 Android 上创建 Web 服务器。它是开源的,您可以在 GitHub 上查看源代码。
服务器还可以轻松嵌入到您的 Android 应用程序中,例如:
使用 servlet 概念简化了 Web 服务器的创建,因为您可以专注于应用程序所需的业务逻辑,并将所有 HTTP 工作委托给 servlet 引擎。
Your question has a very good pool of answers covering a creation web server just using Java SE. However, some people can be interesting in a similar solution running on the Android platform. It's very naturally limited to Java SE and even a max JVM version can be limited to Java 8. I use Atjeews for creation web server on Android. It's open source and you can check sources at GitHub.
The server can be also easily embedded in your Android application, for example:
Using servlet concept simplifies creation of a web server, because you can be focused on a business logic required to your app and delegate all HTTP work to a servlet engine.
从 Java SE 6 开始,
SunOracle JRE 中有一个内置 HTTP 服务器。 Java 9 模块名称为 <代码>jdk.httpserver。com.sun.net.httpserver
包摘要 概述了涉及的类并包含示例。这是他们文档中复制粘贴的启动示例。您只需在 Java 6+ 上复制、粘贴并运行即可。
(对于所有试图编辑它的人来说,因为这是一段丑陋的代码,请不要,这是复制粘贴,不是我的,此外,你永远不应该编辑引用,除非它们在原始来源)
应该注意的是,他们的示例中的
response.length()
部分很糟糕,它应该是response.getBytes().length
。即使这样,getBytes()
方法也必须显式指定您随后在响应标头中指定的字符集。唉,虽然误导了初学者,但这毕竟只是一个基本的启动示例。执行它并访问 http://localhost:8000/test,您将看到以下响应:
,请注意,与某些开发人员的想法相反,众所周知的常见问题解答 为什么开发人员不应该编写调用“sun”包的程序。该常见问题解答涉及 Oracle JRE 内部使用的
sun.*
包(例如sun.misc.BASE64Encoder
)(因此,当您在不同的 JRE),而不是 com.sun.* 包。 Sun/Oracle 也像 Apache 等其他公司一样,在 Java SE API 本身之上开发软件。此外,这个特定的HttpServer
必须存在于每个 JDK 中,因此绝对不会出现像sun.*
包那样的“可移植性”问题。仅当涉及某个对象的实现时,才不鼓励使用com.sun.*
类(但不禁止)某些Java API,例如GlassFish(Java EE impl)、Mojarra(JSF impl)、Jersey(JAX-RS impl)等。Since Java SE 6, there's a builtin HTTP server in
SunOracle JRE. The Java 9 module name isjdk.httpserver
. Thecom.sun.net.httpserver
package summary outlines the involved classes and contains examples.Here's a kickoff example copypasted from their docs. You can just copy'n'paste'n'run it on Java 6+.
(to all people trying to edit it nonetheless, because it's an ugly piece of code, please don't, this is a copy paste, not mine, moreover you should never edit quotations unless they have changed in the original source)
Noted should be that the
response.length()
part in their example is bad, it should have beenresponse.getBytes().length
. Even then, thegetBytes()
method must explicitly specify the charset which you then specify in the response header. Alas, albeit misguiding to starters, it's after all just a basic kickoff example.Execute it and go to http://localhost:8000/test and you'll see the following response:
As to using
com.sun.*
classes, do note that this is, in contrary to what some developers think, absolutely not forbidden by the well known FAQ Why Developers Should Not Write Programs That Call 'sun' Packages. That FAQ concerns thesun.*
package (such assun.misc.BASE64Encoder
) for internal usage by the Oracle JRE (which would thus kill your application when you run it on a different JRE), not thecom.sun.*
package. Sun/Oracle also just develop software on top of the Java SE API themselves like as every other company such as Apache and so on. Moreover, this specificHttpServer
must be present in every JDK so there is absolutely no means of "portability" issue like as would happen withsun.*
package. Usingcom.sun.*
classes is only discouraged (but not forbidden) when it concerns an implementation of a certain Java API, such as GlassFish (Java EE impl), Mojarra (JSF impl), Jersey (JAX-RS impl), etc.查看 NanoHttpd
它正在 Github 上开发,并使用 Apache Maven 进行构建和部署。单元测试”
Check out NanoHttpd
It is being developed at Github and uses Apache Maven for builds & unit testing"
com.sun.net.httpserver 解决方案不可跨 JRE 移植。最好使用 javax.xml.ws 中的官方 Webservices API 来引导最小的 HTTP 服务器...
编辑:这确实有效!上面的代码看起来像 Groovy 之类的。这是我测试过的 Java 翻译:
The com.sun.net.httpserver solution is not portable across JREs. Its better to use the official webservices API in javax.xml.ws to bootstrap a minimal HTTP server...
EDIT: this actually works! The above code looks like Groovy or something. Here is a translation to Java which I tested:
我喜欢这个问题,因为这是一个不断创新的领域,并且总是需要一个轻型服务器,特别是在谈论小型设备中的嵌入式服务器时。我认为答案分为两大类。
虽然我可能会考虑使用 HTTP 库,例如:Jetty、Apache Http 组件, Netty 等更像是一个原始的 HTTP 处理设施。标签是非常主观的,取决于您被要求为小型站点提供的内容类型。我本着问题的精神做出这种区分,特别是关于...
这些原始工具可以让您做到这一点(如其他答案)。他们并不真正适合以现成的方式制作轻型、嵌入式或迷你服务器。迷你服务器可以为您提供与全功能 Web 服务器类似的功能(例如 Tomcat< /a>) 没有花里胡哨的功能,体积小,99% 的时间都具有良好的性能。瘦服务器似乎更接近原始措辞,只是比原始措辞多一点,也许具有有限的子集功能,足以让您在 90% 的时间里看起来不错。我对 raw 的想法是让我在 75% - 89% 的时间里看起来不错,而不需要额外的设计和编码。我认为,如果/当你达到 WAR 文件的级别时,我们就为 bonsi 服务器留下了“小”,看起来大服务器所做的一切都变得更小。
瘦服务器选项
迷你服务器选项:
在其他需要考虑的事情中,我会包括身份验证、验证、国际化,使用诸如 FreeMaker 之类的东西 或其他模板工具来渲染页面输出。否则,管理 HTML 编辑和参数化可能会使 HTTP 的使用看起来像是毫无意义的事情。当然,这完全取决于您需要的灵活性。如果它是菜单驱动的传真机,那就非常简单了。交互越多,您的框架就需要“越厚”。好问题,祝你好运!
I like this question because this is an area where there's continuous innovation and there's always a need to have a light server especially when talking about embedded servers in small(er) devices. I think answers fall into two broad groups.
While I might consider HTTP libraries like: Jetty, Apache Http Components, Netty and others to be more like a raw HTTP processing facilities. The labelling is very subjective, and depends on the kinds of thing you've been call-on to deliver for small-sites. I make this distinction in the spirit of the question, particularly the remark about...
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.
Thin-server options
Mini-server options:
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!
查看“Jetty”Web 服务器 Jetty。出色的开源软件,似乎可以满足您的所有要求。
如果您坚持自己动手,请查看“httpMessage”类。
Have a look at the "Jetty" web server Jetty. Superb piece of Open Source software that would seem to meet all your requirments.
If you insist on rolling your own then have a look at the "httpMessage" class.
曾几何时,我一直在寻找类似的东西——一个轻量级但功能齐全的 HTTP 服务器,我可以轻松嵌入和定制它。我发现了两种类型的潜在解决方案:
所以...我开始编写 JLHTTP - Java 轻量级 HTTP 服务器。
您可以将其作为单个(如果相当长)源文件或作为约 50K jar(约 35K 剥离)的没有依赖项的嵌入到任何项目中。它力求符合 RFC 标准,并包含大量文档和许多有用的功能,同时将膨胀降至最低。
功能包括:虚拟主机、磁盘文件服务、通过标准 mime.types 文件进行 mime 类型映射、目录索引生成、欢迎文件、支持所有 HTTP 方法、条件 ETag 和 If-* 标头支持、分块传输编码、gzip/deflate压缩、基本 HTTPS(由 JVM 提供)、部分内容(下载继续)、文件上传的多部分/表单数据处理、通过 API 或注释的多个上下文处理程序、参数解析(查询字符串或 x-www-form-urlencoded) body)等。
我希望其他人觉得它有用:-)
Once upon a time I was looking for something similar - a lightweight yet fully functional HTTP server that I could easily embed and customize. I found two types of potential solutions:
So... I set out to write JLHTTP - The Java Lightweight HTTP Server.
You can embed it in any project as a single (if rather long) source file, or as a ~50K jar (~35K stripped) with no dependencies. It strives to be RFC-compliant and includes extensive documentation and many useful features while keeping bloat to a minimum.
Features include: virtual hosts, file serving from disk, mime type mappings via standard mime.types file, directory index generation, welcome files, support for all HTTP methods, conditional ETags and If-* header support, chunked transfer encoding, gzip/deflate compression, basic HTTPS (as provided by the JVM), partial content (download continuation), multipart/form-data handling for file uploads, multiple context handlers via API or annotations, parameter parsing (query string or x-www-form-urlencoded body), etc.
I hope others find it useful :-)
JEP 408:简单的 Web 服务器
从 Java 18 开始,您可以使用 Java 标准库创建简单的 Web 服务器:
默认情况下,这将显示您指定的根目录的目录列表。您可以在该目录中放置一个 index.html 文件(以及 CSS 和 JS 文件等其他资源)来显示它们。
旁注
对于 Java 标准库 HTTP 客户端,请参阅帖子 Java 11 新的 HTTP 客户端 API 以及JEP 321。
JEP 408: Simple Web Server
Starting in Java 18, you can create simple web servers with Java standard library:
This will, by default, show a directory listing of the root directory you specified. You can place an index.html file (and other assets like CSS and JS files) in that directory to show them instead.
Sidenote
For Java standard library HTTP client, see the post Java 11 new HTTP Client API and also JEP 321.
Spark是最简单的,这里有一个快速入门指南:http://sparkjava.com/
Spark is the simplest, here is a quick start guide: http://sparkjava.com/
以上所有答案都详细介绍了单主线程请求处理程序。
设置:
允许使用执行程序服务通过多个线程提供多个请求服务。
所以最终代码将如下所示:
All the above answers details about Single main threaded Request Handler.
setting:
Allows multiple request serving via multiple threads using executor service.
So the end code will be something like below:
只需几行代码,只需使用 JDK 和 servlet api,就可以创建一个为 J2EE servlet 提供基本支持的 httpserver。
我发现这对于单元测试 servlet 非常有用,因为它的启动速度比其他轻量级容器快得多(我们使用 jetty 进行生产)。
大多数非常轻量级的 httpserver 不提供对 servlet 的支持,但我们需要它们,所以我想我应该分享。
下面的示例提供了基本的 servlet 支持,或者对于尚未实现的内容抛出 UnsupportedOperationException。它使用 com.sun.net.httpserver.HttpServer 来提供基本的 http 支持。
It's possible to create an httpserver that provides basic support for J2EE servlets with just the JDK and the servlet api in a just a few lines of code.
I've found this very useful for unit testing servlets, as it starts much faster than other lightweight containers (we use jetty for production).
Most very lightweight httpservers do not provide support for servlets, but we need them, so I thought I'd share.
The below example provides basic servlet support, or throws and UnsupportedOperationException for stuff not yet implemented. It uses the com.sun.net.httpserver.HttpServer for basic http support.
您还可以查看一些 NIO 应用程序框架,例如:
You may also have a look at some NIO application framework such as:
这段代码比我们的更好,你只需要添加2个库:javax.servelet.jar和org.mortbay.jetty.jar。
Jetty 类:
Servlet 类:
This code is better than ours, you only need to add 2 libs: javax.servelet.jar and org.mortbay.jetty.jar.
Class Jetty:
Servlet class:
TCP 套接字级别的非常基本的 HTTP 服务器示例:
该示例提供计算机的主机名。
An example of a very basic HTTP server on TCP sockets level:
The example serves the hostname of the computer.
我强烈建议您研究 Simple,特别是如果您不需要 Servlet 功能而只需访问请求/响应对象。如果你需要 REST,你可以将 Jersey 放在上面,如果你需要输出 HTML 或类似的东西,可以使用 Freemarker。我真的很喜欢用这个组合可以做的事情,而且需要学习的 API 相对较少。
I can strongly recommend looking into Simple, especially if you don't need Servlet capabilities but simply access to the request/reponse objects. If you need REST you can put Jersey on top of it, if you need to output HTML or similar there's Freemarker. I really love what you can do with this combination, and there is relatively little API to learn.
签出简单。它是一个非常简单的嵌入式服务器,内置支持多种操作。我特别喜欢它的线程模型..
太棒了!
checkout Simple. its a pretty simple embeddable server with built in support for quite a variety of operations. I particularly love its threading model..
Amazing!
查看
需要
。请参阅 https://github.com/yegor256/takes 了解快速信息Check out
takes
. Look at https://github.com/yegor256/takes for quick info试试这个 https://github.com/devashish234073/ Java-Socket-Http-Server/blob/master/README.md
该 API 使用套接字创建了一个 HTTP 服务器。
例如,以下是 Response.java 类中的构造函数如何将原始响应转换为 http 响应:
Try this https://github.com/devashish234073/Java-Socket-Http-Server/blob/master/README.md
This API has creates an HTTP server using sockets.
For example the here's how the constructor in the
Response.java
class converts a raw response into an http response:Apache Commons HttpCore 项目怎么样?
来自网站:...
HttpCore 目标
API
How about Apache Commons HttpCore project?
From the web site:...
HttpCore Goals
API
您可以编写一个非常简单的 嵌入式 Jetty Java 服务器。
嵌入式 Jetty 意味着服务器 (Jetty) 与应用程序一起提供,而不是将应用程序部署在外部 Jetty 服务器上。
因此,如果采用非嵌入式方法,您的 Web 应用程序内置到部署到某个外部服务器的 WAR 文件中(Tomcat / Jetty /etc),在嵌入式 Jetty 中,您可以在同一代码库中编写 web 应用程序并实例化 jetty 服务器。
嵌入式 Jetty Java 服务器的示例,您可以 git 克隆 并使用:https:// /github.com/stas-slu/embedded-jetty-java-server-example
You can write a pretty simple embedded Jetty Java server.
Embedded Jetty means that the server (Jetty) shipped together with the application as opposed of deploying the application on external Jetty server.
So if in non-embedded approach your webapp built into WAR file which deployed to some external server (Tomcat / Jetty / etc), in embedded Jetty, you write the webapp and instantiate the jetty server in the same code base.
An example for embedded Jetty Java server you can git clone and use: https://github.com/stas-slu/embedded-jetty-java-server-example
自 Java 11 起,旧的 com.sun.net.httpserver 再次成为公共且可接受的 API。您可以将其作为 HttpServer 类获取,该类作为
的一部分提供jdk.httpserver
模块。请参阅 https://docs.oracle.com/en/java/javase/11/docs/api/jdk.httpserver/com/sun/net/httpserver/HttpServer.html因此,除了它的局限性之外,没有理由再避免使用它。
我用它在服务器应用程序中发布控制界面。从客户端请求中读取
User-agent
标头,我什至以text/plain
响应curl
等 CLI 工具,或者以更优雅的 HTML 方式响应任何其他浏览器。又酷又简单。
The old
com.sun.net.httpserver
is again a public and accepted API, since Java 11. You can get it asHttpServer
class, available as part ofjdk.httpserver
module. See https://docs.oracle.com/en/java/javase/11/docs/api/jdk.httpserver/com/sun/net/httpserver/HttpServer.htmlSo, apart from its limitations, there is no reason to avoid its use anymore.
I use it to publish a control interface in server applications. Reading the
User-agent
header from a client request I even respond intext/plain
to CLI tools likecurl
or in more elegant HTML way to any other browser.Cool and easy.