HTTP Web Server: Java

jnbgames.dev 1 Tallied Votes 158 Views Share

The program below is written in Java and is used to develop a Web Server that supports these status codes: 200 OK, 302 Moved Temporarily, and 404 NOT FOUND. The code can emulate an HTTP server in your local machine. Let me know if you find the code below helpful and if you have any additional suggestions:

/*
 * An HTTP Web Server that supports these status codes: 200 OK, 302 Moved Temporarily and 404 NOT FOUND.
 * The code can be tested using any Web Browser.
 */

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author jnbgames.dev
 */
public class HTTPWebServer {

    private static ServerSocket serverSocket;

    public static void main(String[] args) throws IOException {

        // give some values
        String port = "7788"; // if not specified
        String redirection = "https://www.daniweb.com/"; // if not specified
        String redirector = "test.txt"; //if not specified

        // Open the Server Socket and bind it to admin specified port
        serverSocket = new ServerSocket(Integer.valueOf(port));

        while (true) {

            System.out.println("HTTP Web Server is waiting...");

            // Open a new Thread and pass in Socket && REDIRECTIONS info
            new HttpServerThread(serverSocket.accept(), redirection, redirector);

        }
    }
}

class HttpServerThread extends Thread {

    private Socket connectionFromBrowser;
    private BufferedReader in;
    private PrintWriter out;
    private String redirection;
    private String redirector;

    public HttpServerThread(Socket connectionFromClient, String redirection, String redirector) throws IOException {

        this.connectionFromBrowser = connectionFromClient;
        this.in = new BufferedReader(new InputStreamReader(connectionFromBrowser.getInputStream()));
        this.out = new PrintWriter(connectionFromBrowser.getOutputStream());
        this.redirection = redirection;
        this.redirector = redirector;
        start();

    }

    public void run() {
        try {
            System.out.println("Connection established in " + connectionFromBrowser.getInetAddress().getHostName());

            // read HTTP request line
            String request = in.readLine();

            // Get filename in the request
            if (request.compareToIgnoreCase("GET / HTTP/1.1") == 0 || request.compareToIgnoreCase("GET / HTTP/1.0") == 0) {
                http200();
            } else if (request.regionMatches(5, redirector, 0, redirector.length())) {
                http302(redirection);
            } else {
                http404();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // method for 404
    public void http404() throws IOException {

        // Create HTTP Response Header
        String header404 = "HTTP/1.1 404 Not Found\r\n"
                + "Content-type: text/html\r\n\r\n";

        // Create message body  
        String html404 = "<html>\n"
                + "<body>\n"
                + "	<hgroup>\n"
                + "		<center>\n"
                + "			<h1>404</h1>\n"
                + "				 \n"
                + "			<h1>Page Not Found</h1>\n"
                + "		</center> \n"
                + "	</hgroup>\n"
                + "</body>\n"
                + "</html>";

        // send HTTP 404 Response
        out.println(header404 + html404);
        out.flush();
        connectionFromBrowser.close();
    }

    // method of 302
    public void http302(String red) throws IOException {
        // Create HTTP Response Header
        String header302 = "HTTP/1.1 302 Moved Temporarily\r\n"
                + "Location: " + red + "\r\n\r\n";

        // send HTTP 302 
        out.println(header302);
        out.flush();
        connectionFromBrowser.close();
    }

    // method 200
    public void http200() throws IOException {

        // Create HTTP Response Header
        String header200 = "HTTP/1.1 200 OK\r\n"
                + "Content-Type: text/html\r\n"
                + "Server: Simo\r\n\r\n";

        // Create simple HTML message to display
        String html = "<html>\n"
                + "<body>\n"
                + "	<hgroup>\n"
                + "		<center>\n"
                + "			<h1> Welcome to Server 01</h1>\n"
                + "		</center> \n"
                + "	</hgroup>\n"
                + "</body>\n"
                + "</html>";

        // Send HTTP 200 OK Response & HTML CONTENT
        out.println(header200 + html);
        out.flush();
        connectionFromBrowser.close();
    }
}
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That’s a great contribution. Thanks.
I think most of us have written something like that for our private libraries, and as of Java 18 it seems people have noticed.
“Text blocks” allow you to code literal multi-line formatted text such as your html in a straightforward way.
The jdk now comes with a simple web server as standard.

commented: I agree with you! I will try text blocks, they will be much helpful in this case! +0
Dani 4,084 The Queen of DaniWeb Administrator Featured Poster Premium Member

Is code like this still necessary anymore with the JDK including a web server by default, then?

rproffitt 2,580 "Nothing to see here." Moderator

Nice to see such efforts still going on.

As to if it's needed, a long time ago we had this GPS tracker and it run on a slimmed down Linux but the code for the app was Java. There was a mini-web server component as well.

This was a long time before the JDK supplied a web server and memory was not exactly plentiful. I think the whole thing ran on 1 megabyte with a single core ARM CPU.

Dani 4,084 The Queen of DaniWeb Administrator Featured Poster Premium Member

I’ll take that to mean that there’s no advantage to not using the JDK in 2022.

rproffitt 2,580 "Nothing to see here." Moderator

I think the no advantage was a remark to me. Even today, for embedded applications (now often called Internet of Things) we often have to turn to reduced footprint methods. The JDK server may incur an extra cost for more RAM. When you are dealing with devices such as GPS trackers, if you can slim down the RAM and CPU requirements you can drop a few dollars off the product cost and even reduce battery size or increase time on battery power.

Dani 4,084 The Queen of DaniWeb Administrator Featured Poster Premium Member

My comment was specific to this code snippet. Why would an embedded device run a Java based web server that requires a JRE, etc? Wouldn’t it be more appropriate to be written in C if you need such close control over memory management, etc?

rproffitt 2,580 "Nothing to see here." Moderator

Dani, great question. When we were evaluating possible designs a few were ARM SoC based with Linux and JRE implementations. Times change and before we would scale a solution picking chips, OS or even no OS, build prototypes and do the usual engineering samples to the field but with outsourcing and a wide array of designs that were very close to what we required we traveled about Taiwan meeting with various companies to see what they offered.
One or more of the devices in the run off had the ARM+Linux+JRE stack and the JRE made it fairly trivial to customize the product. Now the dev kit was a bit rough so I spent a week in Taiwan with the company to create an easy to deploy dev kit with a short manual on install and use.

We didn't need close control, just needed to keep it from needing more CPU or RAM.

I have another project that we needed absolute control so I used an Atmel 8 pin microcontroller with no RAM. The embedded software was assembler and ran great with a few spare registers left when done. Cost was key here so the micro came in at a hefty 26 cents.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I think the point is that when trying out ideas in Java you sometimes need something to deliver done html to a browser. You don’t need to set up and configure a full-feature server, just do something very very basic with no question of using it in a live production environment.
That’s why it eventually got included in the jdk.
It is, by the way, a really good app to write to learn about server sockets etc.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.