Pengembangan Server HTTP Java Menggunakan JDK HttpServer

Tutorial kali ini akan membahas tentang bagaimana menggunakan modul jdk.httpserver untuk pengembangan server HTTP dengan bahasa pemrograman java. Modul ini sangat berguna untuk pengembangan embedded server atau aplikasi web sederhana. Modul ini tersedia dalam Java Development Kit, yang memungkinkan implementasi HTTP tanpa melibatkan library pihak ketiga. Dalam tutorial ini akan dijelaskan pengkodean dasar server HTTP dan bagaimana menangani request menggunakan beragam class yang tersedia dalam modul jdk.httpserver.

Pengantar

Hypertext Transfer Protocol (HTTP) adalah protokol komunikasi yang umum digunakan dalam aplikasi web. Fungsi protokol ini disediakan di beragam bahasa pemrograman. Spesifik untuk bahasa pemrograman java, protokol ini didukung melalui ketersediaan modul jdk.httpserver (lihat dokumentasi). Contoh implementasi sederhana dari modul tersebut adalah SimpleFileServer yang bisa dieksekusi menggunakan perintah jwebserver (lihat tulisan sebelumnya).

Modul ini terdiri atas dua paket, dimana class-class pokok terdapat pada paket com.sun.net.httpserver (lihat dokumentasi). Untuk mempersingkat tutorial ini, pembahasan akan difokuskan pada class dalam paket tersebut.

Contoh Program

Direktori Project

Untuk mempermudah dalam pembuatan program, kita susun struktur direktori project seperti berikut :

httpserver-exc
+- source
+- class

Dalam folder httpserver-exc, kita siapkan dua folder source untuk menyimpan kode program .java dan folder class untuk menampung file .class hasil proses kompilasi. Untuk mempermudah proses kompilasi dan eksekusi program, kita akan gunakan dua buah file batch dengan kode berikut ini :

@echo off
IF EXIST class. RD /S /Q class
DIR /S /B source\*.java > sources.txt
javac @sources.txt -d class
DEL sources.txt

Ketikkan kode diatas kemudian simpan dengan nama compile.bat pada folder httpserver-exc.

@echo off
java -cp class com.sad301.exc.httpserver.Main

Ketikkan kode diatas kemudian simpan dengan nama exec.bat pada folder httpserver-exc.

Berikutnya kita akan membutuhkan file module-info.java. Didalam file tersebut, kita perlu menyebutkan modul yang akan digunakan didalam program, dalam hal ini adalah modul jdk.httpserver. Ketikkan kode dibawah kemudian simpan dengan nama module-info.java dalam folder source.

module httpserver.exc {
  requires jdk.httpserver;
}

Sampai tahap ini, direktori project program adalah sebagai berikut :

httpserver-exc
+- compile.bat
+- exec.bat
+- class
+- source
   +- module-info.java

Class HttpServer

Disini kita akan mulai mengetikkan kode program java, dimulai dengan class utama yang akan menjadi entry point dari program. Ketikkan kode program dibawah, kemudian simpan dengan nama Main.java pada folder source.

package com.sad301.exc.httpserver;

import com.sun.net.httpserver.*;
import java.io.*;
import java.net.*;

public class Main {
  public static void main(String[] args) {
    // Kode selanjutnya diketik pada baris ini
  }
}

Didalam class tersebut, kita gunakan objek HttpServer (lihat dokumentasi) yang akan melayani permintaan HTTP pada saat program dijalankan. Untuk membentuk objek HttpServer, class ini menyediakan beberapa metode statik. Metode yang kita gunakan disini adalah HttpServer.create(InetSocketAddress addr, int backlog). Dalam pemanggilannya, metode ini berpeluang menghasilkan eksepsi IOException sehingga harus dipanggil dalam pernyataan try dan catch.

Perhatikan contoh dibawah :

try {
  HttpServer server = HttpServer.create(new InetSocketAddress(9091), 0);
  // kode selanjutnya diketik pada baris ini
}
catch(IOException exc) {
  exc.printStackTrace();
}

Metode ini menggunakan dua parameter, yaitu objek InetSocketAddress dan nilai socket backlog dengan tipe integer.

Parameter InetSocketAddress (lihat dokumentasi) mengindikasikan alamat dan/atau port yang diasosiasikan dengan server tersebut. Pada contoh diatas, kita hanya menyebutkan nomor port 9091. Konfigurasi ini memungkinkan akses ke server dari perangkat manapun dalam jaringan.

Parameter kedua yaitu socket backlog mengatur berapa banyak koneksi masuk yang akan dilayani oleh server. Nilai 0 mengindikasikan bahwa server akan menggunakan nilai default dalam sistem operasi.

Pemetaan URL dan Penanganan Request

Setelah membuat dan mengkonfigurasikan objek server, tahap berikutnya adalah memetakan tiap URL didalam server dan menentukan bagaimana server akan menangani request yang masuk ke URL tersebut.

Untuk tahap ini kita gunakan metode createContext(String path, HttpHandler handler) dari objek HttpServer. metode ini terdiri atas dua parameter, yaitu :

  • Nilai string path yang mengindikasikan direktori, file atau resource
  • Interface HttpHandler menentukan bagaimana request ke path akan ditangani

Dalam interface HttpHandler (lihat dokumentasi) terdapat satu signature metode yang harus didefinisikan yaitu handle(HttpExchange exchange). Didalam parameter HttpExchange (lihat dokumentasi) kita bisa mengakses informasi perihal request dan menentukan bagaimana meresepon request tersebut.

Karena HttpHandler adalah interface dengan 1 buah metode, kita bisa langsung definisikan implementasinya dalam bentuk ekspresi lambda (lihat tulisan sebelumnya). Perhatikan contoh kode dibawah :

server.createContext("/", exchange -> {
  // kode selanjutnya diketik pada baris ini
});

Sampai disini kita bisa mulai melayani request dari client. Disini kita tidak mencoba mendapatkan informasi mendetail seputar request, tetapi hanya mengirimkan response berupa halaman web tiap kali ada request yang diterima.

Disini kita akan gunakan 3 buah metode didalam HttpExchange, yaitu :

  • getResponseHeaders(). Metode ini mengembalikan objek Headers yang merepresentasikan header dari response. Objek tersebut kita gunakan untuk men-set nilai header Content-Type dari pesan response yang akan dikirimkan.
  • sendResponseHeaders(int rCode, long responseLength). Metode ini bertujuan untuk mengirimkan header dari response. Metode ini menggunakan dua parameter yaitu kode HTTP (rCode) dan panjang dari pesan response (responseLength).
  • getResponseBody(). Metode ini mengembalikan objek OutputStream untuk fungsi pengirimkan pesan response kepada client.

Perhatikan contoh kode berikut :

String pesan = "<!DOCTYPE html>" +
  "<html lang=\"id\">" +
  "<head><title>Selamat Datang</title></head>" +
  "<body><h1>Selamat Datang</h1><p>Halaman ini berasal dari server HTTP java</p></body>" +
  "</html>";
exchange.getResponseHeaders().set("Content-Type", "text/html");
exchange.sendResponseHeaders(200, pesan.length());
OutputStream out = exchange.getResponseBody();
out.write(pesan.getBytes());
out.close();

Mengaktifkan Server HTTP

Langkah terakhir adalah mengaktifkan server yang sudah dikonfigurasikan sebelumnya. Disini kita cukup memanggil metode start() dari objek HttpServer.

Dibawah ini adalah kode program selengkapnya

package com.sad301.exc.httpserver;

import com.sun.net.httpserver.*;
import java.io.*;
import java.net.*;

public class Main {
  public static void main(String[] args) throws IOException {
    HttpServer server = HttpServer.create(new InetSocketAddress(9091), 0);
    server.createContext("/", exchange -> {
      String pesan = "<!DOCTYPE html>" +
        "<html lang=\"id\">" +
        "<head><title>Selamat Datang</title></head>" +
        "<body><h1>Selamat Datang</h1><p>Halaman ini berasal dari server HTTP java</p></body>" +
        "</html>";
      exchange.getResponseHeaders().set("Content-Type", "text/html");
      exchange.sendResponseHeaders(200, pesan.length());
      OutputStream out = exchange.getResponseBody();
      out.write(pesan.getBytes());
      out.close();
    });
    server.start();
    System.out.println("Server listening at 9091");
  }
}

Compile kode program diatas menggunakan perintah compile.bat dan eksekusi program dengan perintah exec.bat. Pada saat dijalankan, program akan menampilkan text “Server listening at 9091”. Setelah mengeksekusi program, jalankan aplikasi web browser kemudian ketikkan alamat http://127.0.0.1:9091 pada kotak address bar.

Menggunakan Perintah jwebserver

Tulisan kali ini akan membahas tentang bagaimana menggunakan perintah jwebserver untuk mengeksekusi web server sederhana. jwebserver merupakan tool command line yang disediakan dalam rilis Java Development Kit (JDK) versi 18. Tool ini menyediakan fitur minimum HTTP server, yang bisa digunakan untuk sekedar melayani permintaan berupa file statis pada direktori yang ditentukan. Tool ini akan sangat bermanfaat untuk keperluan testing dan debugging aplikasi web sisi client yang berbasis HTML, CSS dan JavaScript.

Merujuk ke dokumentasinya, jwebserver hanya melayani request dengan metode HEAD dan GET, metode lain akan direspon dengan kode 501 atau 405. Yang artinya, fungsi HTML form submit dengan metode POST tidak bisa digunakan.

Untuk menggunakan jwebserver, pastikan JDK 18 sudah terinstall di perangkat yang kita gunakan. Untuk memeriksa versi JDK, kita bisa gunakan perintah java -version.

C:\Users\User>java -version
java version "18" 2022-03-22
Java(TM) SE Runtime Environment (build 18+36-2087)
Java HotSpot(TM) 64-Bit Server VM (build 18+36-2087, mixed mode, sharing)

JDK 18 bisa didapatkan di halaman download dari website resminya. Untuk instalasi dan konfigurasinya, anda bisa ikuti tutorial pada halaman ini. Pastikan variable sistem JAVA_HOME dan PATH sudah dikonfigurasikan dengan benar.

Untuk ekesekusinya, kita cukup ketikkan perintah jwebserver di jendela aplikasi Command Prompt. Pada saat dieksekusi, web server akan menampilkan output seperti dibawah

image

Secara default, jwebserver hanya melayani permintaan pada alamat IP 127.0.0.1 (localhost) pada port 8000. Sedangkan direktori file yang dilayani adalah direktori tempat jwebserver dieksekusi (current directory).

Konfigurasi diatas dapat diubah dengan menggunakan opsi-opsi berikut :

  • --bind-address (disingkat -b) berfungsi untuk mengubah alamat IP yang akan melayani permintaan HTTP.
  • --port (disingkat -p) berfungsi untuk mengubah nomor port HTTP
  • --directory (disingkat -d) berfungsi untuk mengubah direktori dari file yang akan dilayani

Sebagai contoh, semisal kita ingin mengeksekusi web server agar bisa diakses dari perangkat lain dalam jaringan 192.168.0.0 (dengan alamat IP perangkat server 192.168.0.17) pada port 8080, dan melayani file pada direktori C:\my-static-site. Perintah yang kita gunakan adalah sebagai berikut :

C:\Users\User>jwebserver --bind-address 192.168.0.17 --port 8080 --directory C:\my-static-site