是否有一种方法可以使用Java SE API在Java中创建一个非常基本的HTTP服务器(只支持GET/POST),而不需要编写代码手动解析HTTP请求和手动格式化HTTP响应?Java SE API在HttpURLConnection中很好地封装了HTTP客户机功能,但是是否有类似的HTTP服务器功能呢?

需要明确的是,我在网上看到的许多ServerSocket示例的问题是,它们自己进行请求解析/响应格式化和错误处理,这很乏味,容易出错,而且不太全面,出于这些原因,我试图避免使用它。


当前回答

从Java SE 6开始,在Sun Oracle JRE中有一个内置的HTTP服务器。Java 9模块名称为jdk.httpserver。httpserver包摘要概述了涉及的类并包含示例。

这里有一个从他们的文档复制粘贴的启动示例。你可以复制,粘贴,然后在Java 6+上运行。 (尽管如此,所有试图编辑它的人,因为它是一段丑陋的代码,请不要,这是一个复制粘贴,不是我的,此外,你不应该编辑引文,除非它们在原始来源中发生了变化)

package com.stackoverflow.q3732109; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class Test { public static void main(String[] args) throws Exception { HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0); server.createContext("/test", new MyHandler()); server.setExecutor(null); // creates a default executor server.start(); } static class MyHandler implements HttpHandler { @Override public void handle(HttpExchange t) throws IOException { String response = "This is the response"; t.sendResponseHeaders(200, response.length()); OutputStream os = t.getResponseBody(); os.write(response.getBytes()); os.close(); } } }

应该注意的是,他们示例中的response.length()部分是坏的,它应该是response.getBytes().length。即使这样,getBytes()方法也必须显式地指定在响应头中指定的字符集。唉,尽管对初学者有误导,但毕竟这只是一个基本的启动示例。

执行它并访问http://localhost:8000/test,你将看到以下响应:

这是反应


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 the sun.* package (such as sun.misc.BASE64Encoder) for internal usage by the Oracle JRE (which would thus kill your application when you run it on a different JRE), not the com.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 specific HttpServer must be present in every JDK so there is absolutely no means of "portability" issue like as would happen with sun.* package. Using com.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.

其他回答

检查拍摄。查看https://github.com/yegor256/takes获取快速信息

我喜欢这个问题,因为这是一个不断创新的领域,总是需要有一个轻型服务器,特别是当谈到小型设备中的嵌入式服务器时。我认为答案可以分为两大类。

瘦服务器:使用最少处理、上下文或会话处理的服务器式静态内容。 小型服务器:从表面上看,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!

我强烈建议考虑Simple,特别是如果您不需要Servlet功能,而只是访问请求/响应对象。如果你需要REST,你可以把Jersey放在上面,如果你需要输出HTML或类似的东西,有Freemarker。我真的很喜欢使用这个组合可以做的事情,而且需要学习的API相对较少。

试试这个https://github.com/devashish234073/Java-Socket-Http-Server/blob/master/README.md

这个API使用套接字创建了一个HTTP服务器。

它以文本的形式从浏览器获取请求 解析它来检索URL信息、方法、属性等。 使用定义的URL映射创建动态响应 将响应发送到浏览器。

例如,下面是response .java类中的构造函数如何将原始响应转换为http响应:

public Response(String resp){
    Date date = new Date();
    String start = "HTTP/1.1 200 OK\r\n";
    String header = "Date: "+date.toString()+"\r\n";
    header+= "Content-Type: text/html\r\n";
    header+= "Content-length: "+resp.length()+"\r\n";
    header+="\r\n";
    this.resp=start+header+resp;
}

你也可以看看一些NIO应用框架,比如:

网状的:http://jboss.org/netty Apache Mina: http://mina.apache.org/或其子项目AsyncWeb: http://mina.apache.org/asyncweb/