仅使用 Java SE API 的 Java 中的简单 HTTP 服务器 [英] Simple HTTP server in Java using only Java SE API

查看:23
本文介绍了仅使用 Java SE API 的 Java 中的简单 HTTP 服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

解决方案

从 Java SE 6 开始,Sun Oracle JRE 中有一个内置的 HTTP 服务器.com.sun.net.httpserver 包摘要 概述了涉及的类并包含示例.

这是从他们的文档中复制粘贴的启动示例(对于所有试图编辑它的人,因为它是一段丑陋的代码,请不要,这是复制粘贴,不是我的,此外,您不应编辑引文,除非它们在原始来源中发生了变化).你可以在 Java 6+ 上复制'n'paste'n'run它.

<块引用>

package com.stackoverflow.q3732109;导入 java.io.IOException;导入 java.io.OutputStream;导入 java.net.InetSocketAddress;导入 com.sun.net.httpserver.HttpExchange;导入 com.sun.net.httpserver.HttpHandler;导入 com.sun.net.httpserver.HttpServer;公共类测试{public static void main(String[] args) 抛出异常 {HttpServer 服务器 = HttpServer.create(new InetSocketAddress(8000), 0);server.createContext("/test", new MyHandler());server.setExecutor(null);//创建一个默认执行器服务器开始();}静态类 MyHandler 实现了 HttpHandler {@覆盖公共无效句柄(HttpExchange t)抛出 IOException {String 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,您将看到以下响应:

<块引用>

这是回复

<小时>

至于使用 com.sun.* 类,请注意,这与某些开发人员的想法相反,绝对没有被众所周知的 FAQ 为什么开发人员不应该编写调用sun"包的程序.该 FAQ 涉及供 Oracle JRE 内部使用的 sun.* 包(例如 sun.misc.BASE64Encoder)(因此当您在不同的 JRE),而不是 com.sun.* 包.Sun/Oracle 也只是在 Java SE API 本身之上开发软件,就像其他所有公司(例如 Apache 等)一样.仅当涉及特定 Java API(例如 GlassFish(Java EE impl)、Mojarra)的实现时,不鼓励(但不禁止)使用 com.sun.* 类(JSF impl)、Jersey (JAX-RS impl) 等

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.

解决方案

Since Java SE 6, there's a builtin HTTP server in Sun Oracle JRE. The com.sun.net.httpserver package summary outlines the involved classes and contains examples.

Here's a kickoff example copypasted from their docs (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). You can just copy'n'paste'n'run it on 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();
        }
    }

}

Noted should be that the response.length() part in their example is bad, it should have been response.getBytes().length. Even then, the getBytes() 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:

This is the 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 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. 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.

这篇关于仅使用 Java SE API 的 Java 中的简单 HTTP 服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆