Simple HTTP server in Java using only Java SE API

http, httpserver, java

Solution

Since Java SE 6, there's a builtin HTTP server in Sun Oracle JRE. The Java 9 module name is `jdk.httpserver`. The `com.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)

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. 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.

Problem

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.

Original source

Related problems