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.