In the first part of this blog series, Simple HTTP Server in Java with TCP Network Programming, we discussed the specifications of HTTP requests and responses according to the RFC standards, and we went through setting up your Java development environment. Now, in Part 2, we’ll dive into writing the actual code to implement our simple HTTP server using Java’s powerful networking capabilities.
Sample Http Request and Response
You can read more about request and response specification in previous blog post Simple HTTP Server in Java with TCP Network Programming
Server Implementation: Handling HTTP Requests in Java
Below is the complete code for our simple single-threaded HTTP server implemented in Java. This server listens for incoming connections, handles HTTP requests, and sends responses in a sequential manner. Given its single-threaded nature, it handles one connection at a time, which is suitable for understanding the basic mechanics of HTTP server operations. As you get more comfortable with these concepts, you might consider implementing multithreading to handle multiple client connections simultaneously.
import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class SimpleHTTPServer { public static void main(String[] args) throws Exception { final ServerSocket server = new ServerSocket(8080); System.out.println("Listening for connection on port 8080 ...."); while (true) { // spin forever Socket socket = server.accept(); System.out.println("Incoming connection from " + socket.getInetAddress()); InputStream input = socket.getInputStream(); OutputStream output = socket.getOutputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); PrintWriter writer = new PrintWriter(output, true); /* As per the HTTP request specification: 1. The first line is the request line. 2. From the second line until an empty line is encountered are the headers. 3. After that, there is an optional body that continues until the end of the stream. */ String requestLine = reader.readLine(); // Read the request line List<String> headers = readHeaders(reader); // Read all headers //we are not reading body for this tutorial purpose; System.out.println("--------Serving Request----------"); System.out.println(); System.out.println(requestLine); System.out.println(headers); String method = requestLine.split(" ")[0]; String path = requestLine.split(" ")[1]; // handle the HTTP request if (method.equals("GET") && "/hi".equals(path)) { writer.println("HTTP/1.1 200 OK"); // status line writer.println("Content-Type: text/html"); // headers writer.println("x-custom-header: custom-server"); writer.println(); writer.println("<html><body><h1>Hello World</h1></body></html>"); } else { // send a 404 error writer.println("HTTP/1.1 404 Not Found"); // status line writer.println("Content-Type: text/html"); // headers writer.println("x-custom-header: custom-server"); writer.println(); writer.println("<html><body><h1>Only the /hi path is served by this simple HTTP server.</h1></body></html>"); } System.out.println(); System.out.println("----Request Served-------"); // close the connection socket.close(); } } static List<String> readHeaders(BufferedReader reader) throws IOException { List<String> headers = new ArrayList<>(); String line = null; //read headers until an empty line is encountered while ((line = reader.readLine()) != null && !line.isEmpty()) { headers.add(line); } return headers; } }
We have read the request line and headers in lines 27 and 28, following the specifications outlined in the inline comments. Subsequently, in lines 38 and 39, we split the request line to extract the method and path. Finally, we send the response in accordance with the specification, as detailed in lines 43 to 47.
Running the Java Server: Console Output
Below, you’ll find the console output demonstrating how our Java server handles incoming HTTP requests when running the code in IntelliJ IDEA. Headers part is cropped.
Response in Browser
Success Response
404 not found response
Conclusion
In this part of the blog series, we have implemented a simple HTTP server that listens on a specified port, accepts client connections, and handles basic GET requests. This server is a foundational step towards building more complex web servers and applications. You can extend this server by adding support for more HTTP methods, handling different content types, or implementing more complex routing and resource management.
Stay tuned for further enhancements and feel free to experiment with adding your own features to this server. The full potential of Java network programming is vast, and this project provides a solid starting point for deeper exploration.
[…] Check out part of blog here: Building a Simple HTTP Server in Java with TCP Network Programming […]