仅使用 Java SE API 的 Java 简单 HTTP 服务器

新手上路,请多包涵

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

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

原文由 asker 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 350
1 个回答

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

这是从他们的文档中 复制粘贴 的启动示例。您可以在 Java 6+ 上复制’n’粘贴’n’运行它。

(对于所有试图编辑它的人来说,因为它是一段丑陋的代码,请不要,这是复制粘贴,不是我的,而且你永远不应该编辑引文,除非它们在原始来源中发生了变化)

 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() 方法也必须显式指定您随后在响应标头中指定的字符集。 las,尽管对初学者有误导作用,但它毕竟只是一个基本的启动示例。

执行它并转到 http://localhost:8000/test ,您将看到以下响应:

这是回应


至于使用 com.sun.* 类,请注意,与一些开发人员的想法相反,众所周知的 FAQ Why Developers Should Not Write Programs That Call ‘sun’ Packages 绝对没有禁止。该常见问题解答涉及 sun.* 包(例如 sun.misc.BASE64Encoder )供 Oracle JRE 内部使用(因此当您在不同的 JRE 上运行它时会杀死您的应用程序),而不是 com.sun.* 包。 Sun/Oracle 也只是在 Java SE API 之上自己开发软件,就像 Apache 等其他公司一样。此外,这个特定的 HttpServer 必须存在于每个 JDK 中,因此绝对没有像 sun.* 包那样的“可移植性”问题。使用 com.sun.* 仅在涉及特定 Java API 的 实现 时不 _鼓励_(但不 _禁止_)类,例如 GlassFish(Java EE impl)、Mojarra(JSF impl)、Jersey(JAX-RS impl) , ETC。

原文由 BalusC 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题