The First Acquaintance With The HTTP Protocol By Writing A Simple Java Web Server

One Of The Smallest Computers In The World Main Photo

I think that it would not be an exaggeration to assert that knowledge and understanding of the essence of the HTTP protocol are necessary for anyone who has decided to seriously address any of the areas of modern Web development. My personal experience suggests that this understanding does not come immediately. I am ashamed to say that there were times when the words GET and POST was for me akin to magic spells, and I did not even suspect the existence of PUT, PATCH and DELETE.

A few months ago, in addition to the actual development, I also began teaching, and the question arose of how to communicate the essence of the HTTP protocol to future Java developers in a simpler and clearer way. After several days of fussing and a number of unsuccessful attempts to make a presentation, an idea arose, and why not write a simple HTTP server in Java, because nothing so well explains the essence of the protocol as its simplest, but working implementation.

As it turned out, this is not difficult at all. Below is the code that will be enough for correct interaction with any browser! All we need is ServerSocket and some standard I/O.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class HttpServer {

    public static void main (String [] args) {
        try (ServerSocket serverSocket = new ServerSocket (8080)) {
            System.out.println ("Server started!");
            
            while (true) {
                // wait for connection
                Socket socket = serverSocket.accept ();
                System.out.println ("Client connected!");

                // for the connected client, open threads
                // read and write
                try (BufferedReader input = new BufferedReader (new InputStreamReader (socket.getInputStream ()));
                     PrintWriter output = new PrintWriter (socket.getOutputStream (), StandardCharsets.UTF_8)) {

                    // waiting for the first line of the request
                    while (! input.ready ());

                    // read and print everything that was sent by the client
                    System.out.println ();
                    while (input.ready ()) {
                        System.out.println (input.readLine ());
                    }

                    // send response
                    output.println ("HTTP / 1.1 200 OK");
                    output.println ("Content-Type: text / html; charset = utf-8");
                    output.println ();
                    output.println ("<p> Hello everyone! </ p>");
                    output.flush ();
                    
                    // at the end of the execution of the try-with-resources block,
                    // and together with them the connection will be closed
                    System.out.println ("Client disconnected!");
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace ();
        }
    }
}

We try to run this code. It should be noted that the port for which the ServerSocket is created should be free. If the specified port is busy, then you need to either release it or use another free port.

After running this code, go to the browser window and type
http://localhost: 8080/in the address bar. If everything went well, then in the browser window we will see the text “Hello to all”, and in the server log there is text similar to the one below:

Server started!
Client connected!

GET /HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,he;q=0.6,de;q=0.5,cs;q=0.4
Cookie: _ga=GA1.1.1849608036.1549463927; portainer.pagination_containers=100; _gid=GA1.1.80775985.1550669456;
If-Modified-Since: Sat, 05 Jan 2019 12:10:16 GMT

Client disconnected!

In the query strings, starting with the second one, there are headers with which the client’s client settings are transmitted to the server. Each header line has the format [header name]: [value]; [value]; … [value].

After the request text is fully read by the server, we send it the simplest answer, the structure of which is quite simple and similar to the request structure. The first line contains the version of the HTTP protocol and the 200 OK code, which will inform the browser that the request has been successfully processed (the code 404 is much better for everyone, isn’t it;)). Then there is only one Content-Type header in which information about the format of the transmitted document (text/HTML) and its encoding (charset = utf-8) is transmitted. The header is followed by a newline (a mandatory requirement of the HTTP protocol) and the actual text that will be displayed in the browser.

That’s all! Of course, this is not all that you need to know about the HTTP protocol and the principles of developing Web servers, but I would not like to complicate this example since its main task is to demonstrate the simplest HTTP communication. In one of my following materials, I will try to develop the topic of studying the HTTP protocol through its implementation.