Encode Base64 di Java โ Contoh java.util.Base64
Gunakan Base64 Encode Online gratis langsung di browser Anda โ tidak perlu instalasi.
Coba Base64 Encode Online Online โSetiap kali saya membuat header HTTP Basic Auth, menyematkan sertifikat di Kubernetes secret, atau mengirim data biner melalui JSON API, langkah pertamanya selalu sama: encode Base64 byte mentah menjadi string yang aman untuk ASCII. Java mempermudah ini dengan java.util.Base64, API standar yang tersedia sejak Java 8 yang menggantikan sun.misc.BASE64Encoder yang sudah deprecated. Untuk encoding sekali pakai tanpa menulis kode, Base64 Encoder ToolDeck menanganinya langsung di browser. Panduan ini mencakup Base64.getEncoder(), getUrlEncoder(), getMimeEncoder(), encoding file, streaming dengan wrap(OutputStream), serta kesalahan yang sering dilakukan bahkan oleh developer Java berpengalaman. Semua contoh dapat dikompilasi di Java 8 hingga Java 21+.
- โBase64.getEncoder().encodeToString(bytes) adalah one-liner standar โ sudah ada di JDK sejak Java 8, tidak berubah di Java 17 dan 21.
- โSelalu teruskan StandardCharsets.UTF_8 ke String.getBytes() sebelum encoding โ menghilangkannya menggunakan default platform yang berbeda antar JVM.
- โgetUrlEncoder() menghasilkan output URL-safe (- menggantikan +, _ menggantikan /) dan withoutPadding() menghilangkan karakter = di akhir.
- โgetMimeEncoder() menyisipkan pemisah baris setiap 76 karakter โ diperlukan oleh email (MIME) dan format sertifikat PEM.
- โUntuk file besar, gunakan Base64.getEncoder().wrap(OutputStream) untuk melakukan streaming tanpa memuat seluruh file ke memori.
Apa itu Encoding Base64?
Base64 mengonversi data biner arbitrer menjadi string yang terdiri dari 64 karakter ASCII yang dapat dicetak: A-Z, a-z, 0-9, +, dan /. Setiap 3 byte input menghasilkan tepat 4 karakter Base64. Jika panjang input bukan kelipatan 3, satu atau dua karakter padding = ditambahkan di akhir. Output yang di-encode selalu kira-kira 33% lebih besar dari data aslinya.
Base64 bukan enkripsi. Siapa pun yang memiliki string hasil encoding dapat men-decode-nya. Tujuannya adalah keamanan transport: header HTTP, payload JSON, dokumen XML, dan isi email adalah protokol berbasis teks yang tidak dapat membawa byte biner mentah tanpa korupsi data. Kasus penggunaan Java yang umum mencakup HTTP Basic Authentication, penyematan sertifikat PEM, penyimpanan data biner di kolom teks database, dan pembuatan segmen token JWT.
deploy-svc:sk_live_4eC39HqLyjWDarjtT1zdp7dc
ZGVwbG95LXN2Yzpza19saXZlXzRlQzM5SHFMeWpXRGFyanRUMXpkcDdkYw==
Base64.getEncoder().encodeToString() โ API Standar
java.util.Base64 diperkenalkan di Java 8 sebagai pengganti resmi untuk sun.misc.BASE64Encoder. Kelas ini menyediakan tiga static factory method โ masing-masing mengembalikan instance kelas bertingkat Base64.Encoder โ yang mencakup tiga varian Base64 yang didefinisikan dalam RFC 4648. Tidak ada library pihak ketiga yang diperlukan. Tidak ada dependensi Maven. Cukup import dan panggil.
Contoh Minimal โ Encode sebuah String
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class EncodeDemo {
public static void main(String[] args) {
String credentials = "monitoring-svc:9f2a7c4e-b1d8-4a3f";
byte[] credentialBytes = credentials.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(credentialBytes);
System.out.println(encoded);
// bW9uaXRvcmluZy1zdmM6OWYyYTdjNGUtYjFkOC00YTNm
}
}Langkah kunci yang sering dilewatkan developer Java pertama kali: sebuah String harus dikonversi ke byte[] sebelum di-encode. Base64 beroperasi pada byte, bukan karakter. encodeToString() menerima byte[] dan mengembalikan String Base64 secara langsung. Jika Anda membutuhkan hasil encoding sebagai byte, gunakan encode(byte[]) โ ini mengembalikan byte[] dari karakter Base64 yang di-encode ASCII, berguna ketika Anda menulis langsung ke OutputStream atau membangun frame protokol biner.
HTTP Basic Auth โ Kasus Penggunaan Paling Umum
HTTP Basic Authentication mungkin adalah alasan paling umum developer Java menggunakan encoding Base64. Spesifikasi (RFC 7617) mengharuskan string kredensial username:password di-encode Base64 dan ditempatkan di header Authorization. Saya sudah sering melihat ini dilakukan salah โ biasanya karena lupa pemisah titik dua atau meng-encode komponen secara terpisah.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class BasicAuthExample {
public static void main(String[] args) throws Exception {
String username = "metrics-exporter";
String apiKey = "sk_live_4eC39HqLyjWDarjtT1zdp7dc";
// username:password โ Base64
String credentials = username + ":" + apiKey;
String authHeader = "Basic " + Base64.getEncoder()
.encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/v2/metrics"))
.header("Authorization", authHeader)
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); // 200
}
}Round-Trip โ Encode dan Decode
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class RoundTrip {
public static void main(String[] args) {
String original = "X-Correlation-ID: req_8a4f2c91-e7b3-4d56-9012-3f7a8b9c0d1e";
// Encode
String encoded = Base64.getEncoder()
.encodeToString(original.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// WC1Db3JyZWxhdGlvbi1JRDogcmVxXzhhNGYyYzkxLWU3YjMtNGQ1Ni05MDEyLTNmN2E4YjljMGQxZQ==
// Decode
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println(original.equals(decoded)); // true
}
}java.util.Base64 identik dari Java 8 hingga Java 17 dan Java 21. Tidak diperlukan migrasi saat mengupgrade JDK. Kode yang sama dikompilasi dan dijalankan di versi mana pun sejak Java 8.Encoding Data Non-String โ byte[], UUID, dan Timestamp
Encoding Base64 di Java selalu dimulai dengan byte[]. String dikonversi melalui getBytes(StandardCharsets.UTF_8), tetapi tipe lain memerlukan langkah konversi terlebih dahulu. UUID, timestamp, dan identifier numerik harus diserialisasi ke representasi string atau byte sebelum dapat di-encode Base64.
UUID โ Encode sebagai Representasi String
import java.util.Base64;
import java.util.UUID;
import java.nio.charset.StandardCharsets;
UUID sessionId = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
String encoded = Base64.getEncoder()
.encodeToString(sessionId.toString().getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// NmJhN2I4MTAtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4UUID Ringkas โ Encode 16 Byte Mentah
Jika Anda menginginkan hasil encoding yang lebih pendek, ekstrak 128 bit UUID sebagai 16 byte mentah, bukan mengonversinya ke bentuk string 36 karakter. Output Base64 berkurang dari 48 karakter menjadi 24.
import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.UUID;
UUID eventId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
ByteBuffer buffer = ByteBuffer.wrap(new byte[16]);
buffer.putLong(eventId.getMostSignificantBits());
buffer.putLong(eventId.getLeastSignificantBits());
String compact = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(buffer.array());
System.out.println(compact);
// VQ6EAOKbQdSnFkRmVUQAAA
// 22 karakter vs 48 untuk pendekatan berbasis stringTimestamp dan Payload Campuran
import java.time.Instant;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
// Simulasi payload bergaya JWT
String payload = String.format(
"{"sub":"usr_7b3c","iss":"auth.internal","iat":%d,"exp":%d}",
Instant.now().getEpochSecond(),
Instant.now().plusSeconds(3600).getEpochSecond()
);
String encoded = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(payload.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// eyJzdWIiOiJ1c3JfN2IzYyIsImlzcyI6ImF1dGguaW50ZXJuYWwiLCJpYXQiOj... (URL-safe, tanpa padding)toString() pada byte[] dengan harapan mendapatkan isinya โ hasilnya adalah identity hash array seperti [B@6d06d69c. Gunakan new String(bytes, StandardCharsets.UTF_8) atau teruskan array byte langsung ke encodeToString().Referensi Method Base64.Encoder
Kelas java.util.Base64 mengekspos tiga factory method, masing-masing mengembalikan Base64.Encoder yang dikonfigurasi untuk varian tertentu. Instance encoder bersifat thread-safe dan stateless โ buat sekali dan gunakan kembali.
Base64.getUrlEncoder() โ Encoding URL-Safe
Encoder URL-safe menggunakan alfabet alternatif di mana + menjadi - dan / menjadi _, sebagaimana didefinisikan dalam RFC 4648 Section 5. Ini penting ketika string Base64 muncul di parameter query URL, nama file, atau nilai cookie โ karakter Base64 standar bertentangan dengan delimiter URL dan karakter yang dicadangkan filesystem.
import java.util.Base64; import java.nio.charset.StandardCharsets; String redirectUri = "https://app.internal/callback?state=auth_pending&nonce=9f2a7c"; byte[] data = redirectUri.getBytes(StandardCharsets.UTF_8); // Encoder standar โ mengandung + dan / yang merusak URL String standard = Base64.getEncoder().encodeToString(data); System.out.println(standard); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s/c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw== // Encoder URL-safe โ aman untuk parameter query dan nama file String urlSafe = Base64.getUrlEncoder().encodeToString(data); System.out.println(urlSafe); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw== // URL-safe tanpa padding โ untuk JWT dan token ringkas String noPadding = Base64.getUrlEncoder().withoutPadding().encodeToString(data); System.out.println(noPadding); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw
Varian withoutPadding() menghilangkan karakter = di akhir. Spesifikasi JWT mengharuskan Base64 URL-safe tanpa padding untuk segmen header dan payload, sehingga getUrlEncoder().withoutPadding() adalah panggilan yang tepat saat membuat atau memanipulasi token JWT secara manual.
withoutPadding() mengembalikan instance encoder baru โ tidak mengubah yang asli. Keduanya dapat ditetapkan ke field static final dan digunakan kembali dengan aman lintas thread.Encode dari File dan Respons API
Dua skenario dunia nyata yang paling umum untuk encoding Base64 di Java: membaca file biner dari disk (sertifikat, gambar, bundle konfigurasi) dan meng-encode data yang diterima dari respons HTTP.
Encode File ke Base64
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
public class FileEncoder {
public static void main(String[] args) {
try {
byte[] fileBytes = Files.readAllBytes(Path.of("certs/server.pem"));
String encoded = Base64.getEncoder().encodeToString(fileBytes);
System.out.printf("Asli: %d bytes%n", fileBytes.length);
System.out.printf("Ter-encode: %d chars%n", encoded.length());
// Tulis konten ter-encode ke file teks
Files.writeString(
Path.of("certs/server.pem.b64"),
encoded
);
} catch (java.io.IOException e) {
System.err.println("Gagal membaca file: " + e.getMessage());
}
}
}Encode Body Respons API
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
public class ApiEncoder {
public static void main(String[] args) {
try {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/v2/reports/weekly.pdf"))
.header("Authorization", "Bearer tok_8f2a9c3d")
.build();
HttpResponse<byte[]> response = client.send(
request, HttpResponse.BodyHandlers.ofByteArray()
);
if (response.statusCode() == 200) {
String encoded = Base64.getEncoder()
.encodeToString(response.body());
System.out.printf("Ter-encode %d bytes โ %d chars%n",
response.body().length, encoded.length());
} else {
System.err.printf("HTTP %d: %s%n",
response.statusCode(),
new String(response.body()));
}
} catch (Exception e) {
System.err.println("Permintaan gagal: " + e.getMessage());
}
}
}Catatan singkat sebelum bagian CLI: jika Anda hanya perlu menempelkan file atau respons API dan mendapatkan output Base64 tanpa menulis kode, Base64 Encoder online menangani input teks maupun biner.
Encoding Base64 via Command-Line
Terkadang Anda hanya perlu meng-encode string atau file dari terminal โ tanpa project Java, tanpa IDE, tanpa langkah build. Sebagian besar sistem Unix dilengkapi perintah base64, dan jika Anda sudah menginstal JDK, Anda bisa menggunakan jshell untuk pendekatan berbasis Java.
# macOS / Linux โ encode sebuah string
echo -n "deploy-bot:sk_prod_9f2a7c4e" | base64
# ZGVwbG95LWJvdDpza19wcm9kXzlmMmE3YzRl
# Encode sebuah file
base64 < certs/server.pem > certs/server.pem.b64
# Menggunakan jshell (JDK 9+)
echo 'System.out.println(java.util.Base64.getEncoder().encodeToString("deploy-bot:sk_prod_9f2a7c4e".getBytes()))' | jshell -
# Menggunakan java langsung dengan one-liner
java -e 'System.out.println(java.util.Base64.getEncoder().encodeToString(args[0].getBytes()))' "my-secret"
# Catatan: java -e memerlukan JDK 23+ (JEP 477)Pendekatan jshell sangat berguna saat Anda perlu memverifikasi bahwa kode Java menghasilkan output yang sama dengan tool Unix, atau saat men-debug ketidaksesuaian antara yang dikirim service Anda dan yang diterima penerima. Saya memiliki alias shell untuk itu.
base64 menggunakan -D untuk decoding. Di Linux (GNU coreutils) menggunakan -d. Perilaku encoding identik di keduanya. Flag -w 0 di Linux menonaktifkan pembungkusan baris pada output, yang biasanya diinginkan saat melakukan pipe ke perintah lain.Apache Commons Codec โ Alternatif Berperforma Tinggi
Untuk sebagian besar aplikasi, java.util.Base64 sudah cukup cepat. Namun jika Anda memproses jutaan operasi encoding dalam loop ketat โ seperti pipeline ingesti log atau message broker dengan throughput tinggi โ Apache Commons Codec layak di-benchmark. Library ini sudah ada sejak jauh sebelum Java 8 dan menyediakan alternatif yang telah teruji dengan permukaan API yang sedikit berbeda.
// Maven: org.apache.commons:commons-codec:1.17.0
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
byte[] telemetryPayload = ("{"service":"metrics-collector","
+ ""host":"prod-east-07","
+ ""cpu_pct":72.4,"
+ ""mem_mb":3891,"
+ ""timestamp":1710523200}")
.getBytes(StandardCharsets.UTF_8);
// Encoding standar
String encoded = Base64.encodeBase64String(telemetryPayload);
// Encoding URL-safe
String urlSafe = Base64.encodeBase64URLSafeString(telemetryPayload);
// Periksa apakah sebuah string adalah Base64 yang valid
boolean valid = Base64.isBase64(encoded);
System.out.println(valid); // trueApache Commons Codec juga menyediakan Base64OutputStream dan Base64InputStream untuk skenario streaming, serta metode validasi yang tidak dimiliki encoder JDK. Jika Commons Codec sudah ada di dependency tree Anda (banyak proyek Apache yang menyertakannya), tidak ada alasan untuk tidak menggunakannya.
Guava BaseEncoding
Library Guava dari Google menyertakan BaseEncoding yang menyediakan API fluent untuk Base64 dengan pemisah baris yang dapat dikonfigurasi, kontrol padding, dan dukungan untuk alfabet standar maupun URL-safe. API-nya terbaca dengan jelas, tetapi menambahkan Guava (sekitar 3 MB) hanya untuk encoding Base64 adalah terlalu berlebihan. Jika Guava sudah ada di proyek Anda untuk koleksi atau utilitas caching-nya, API encoding adalah bonus yang berguna.
// Maven: com.google.guava:guava:33.1.0-jre
import com.google.common.io.BaseEncoding;
import java.nio.charset.StandardCharsets;
byte[] webhookPayload = ("{"event":"deployment.completed","
+ ""repo":"payments-api","
+ ""sha":"a7f2c91e4b3d","
+ ""environment":"production"}")
.getBytes(StandardCharsets.UTF_8);
// Base64 standar
String standard = BaseEncoding.base64().encode(webhookPayload);
// URL-safe
String urlSafe = BaseEncoding.base64Url().encode(webhookPayload);
// Tanpa padding
String noPad = BaseEncoding.base64Url().omitPadding().encode(webhookPayload);
// Dengan pemisah baris (gaya PEM)
String wrapped = BaseEncoding.base64()
.withSeparator("\n", 64)
.encode(webhookPayload);Base64.getMimeEncoder() โ Output MIME dan PEM dengan Pemisah Baris
Encoder MIME menyisipkan pemisah baris \r\n setiap 76 karakter, sesuai dengan spesifikasi MIME (RFC 2045). Sertifikat PEM, lampiran email S/MIME, dan beberapa API lama mengharapkan format ini. Encoder standar dan URL-safe menghasilkan satu baris yang tidak terputus โ jika Anda meneruskan outputnya ke sistem yang mengharapkan Base64 dengan pemisah baris, sistem tersebut mungkin gagal secara diam-diam atau menolak data tersebut.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
// Simulasi body sertifikat PEM
byte[] certData = new byte[256]; // Dalam praktik, baca dari file .der
new java.security.SecureRandom().nextBytes(certData);
// Encoder MIME default โ 76 karakter per baris, pemisah \r\n
String mimeEncoded = Base64.getMimeEncoder().encodeToString(certData);
System.out.println(mimeEncoded);
// QYx2K3p8Xg7JmN1R+wFkLd... (76 karakter)
// Ht5Bv9CzAq0PnSjYl8WxUe... (76 karakter)
// ...
// Encoder MIME kustom โ 64 karakter per baris (standar PEM), pemisah \n
Base64.Encoder pemEncoder = Base64.getMimeEncoder(64, new byte[]{'\n'});
String pemBody = pemEncoder.encodeToString(certData);
System.out.println("-----BEGIN CERTIFICATE-----");
System.out.println(pemBody);
System.out.println("-----END CERTIFICATE-----");getMimeEncoder() untuk token JWT, header HTTP, atau parameter URL. Pemisah baris akan merusak data dalam konteks tersebut. Gunakan getEncoder() atau getUrlEncoder() sebagai gantinya.Streaming File Besar dengan Base64.getEncoder().wrap()
Memuat seluruh file ke dalam byte[] dengan Files.readAllBytes() berfungsi untuk file kecil, tetapi untuk file di atas 50-100 MB Anda berisiko mengalami OutOfMemoryError. JDK menyediakan Base64.getEncoder().wrap(OutputStream), yang mengembalikan OutputStream yang meng-encode data secara langsung saat Anda menulisnya. Byte ter-encode mengalir ke stream yang mendasarinya tanpa menyangga seluruh input.
import java.io.*;
import java.nio.file.*;
import java.util.Base64;
public class StreamingEncoder {
public static void main(String[] args) throws IOException {
Path inputPath = Path.of("backups/database-export.sql.gz");
Path outputPath = Path.of("backups/database-export.sql.gz.b64");
try (
InputStream in = Files.newInputStream(inputPath);
OutputStream fileOut = Files.newOutputStream(outputPath);
OutputStream base64Out = Base64.getEncoder().wrap(fileOut)
) {
byte[] buffer = new byte[8192];
int bytesRead;
long totalBytes = 0;
while ((bytesRead = in.read(buffer)) != -1) {
base64Out.write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
System.out.printf("Streamed %d bytes melalui encoder Base64%n", totalBytes);
}
// Menutup base64Out secara otomatis mem-flush byte padding terakhir
}
}Blok try-with-resources menangani flushing dan penutupan. Satu detail yang sering mengejutkan orang: padding Base64 terakhir hanya ditulis saat OutputStream yang membungkus ditutup. Jika Anda lupa menutupnya (atau hanya menutup stream terluar), beberapa karakter terakhir dari output ter-encode mungkin hilang.
Streaming ke Network Socket
Method wrap() berfungsi dengan OutputStream apa pun โ output file, output socket, body respons HTTP, bahkan ByteArrayOutputStream. Berikut contoh penulisan data ter-encode Base64 langsung ke buffer dalam memori, yang berguna untuk unit testing atau membangun payload yang akan dikirim melalui HTTP:
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try (OutputStream encoder = Base64.getEncoder().wrap(buffer)) {
// Tulis data dalam potongan โ mensimulasikan pembacaan dari stream
encoder.write("chunk-1:telemetry-data-".getBytes(StandardCharsets.UTF_8));
encoder.write("chunk-2:more-payload-".getBytes(StandardCharsets.UTF_8));
encoder.write("chunk-3:final-segment".getBytes(StandardCharsets.UTF_8));
}
String encoded = buffer.toString(StandardCharsets.UTF_8);
System.out.println(encoded);
// Y2h1bmstMTp0ZWxlbWV0cnktZGF0YS1jaHVuay0yOm1vcmUtcGF5bG9hZC1jaHVuay0zOmZpbmFsLXNlZ21lbnQ=
// Verifikasi round-trip
byte[] decoded = Base64.getDecoder().decode(encoded);
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// chunk-1:telemetry-data-chunk-2:more-payload-chunk-3:final-segmentBufferedInputStream dan merupakan keseimbangan yang baik antara penggunaan memori dan overhead system call. Buffer yang lebih kecil meningkatkan jumlah panggilan baca/tulis; buffer yang lebih besar membuang memori tanpa peningkatan throughput yang berarti.Instance Encoder Thread-Safe โ Simpan dan Gunakan Kembali
Base64.Encoder yang dikembalikan oleh factory method bersifat immutable dan thread-safe. Memanggil Base64.getEncoder() pada setiap operasi encoding membuat objek baru setiap kali. JVM kemungkinan akan mengoptimasi ini, tetapi menyimpan encoder dalam field static final membuat niat lebih jelas dan menghindari alokasi yang tidak perlu di hot path.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class TokenService {
// Buat sekali, gunakan di mana saja โ thread-safe
private static final Base64.Encoder STANDARD = Base64.getEncoder();
private static final Base64.Encoder URL_SAFE = Base64.getUrlEncoder().withoutPadding();
private static final Base64.Encoder MIME = Base64.getMimeEncoder();
public static String encodeForHeader(String value) {
return STANDARD.encodeToString(value.getBytes(StandardCharsets.UTF_8));
}
public static String encodeForUrl(byte[] data) {
return URL_SAFE.encodeToString(data);
}
public static String encodeForEmail(byte[] attachment) {
return MIME.encodeToString(attachment);
}
}Pola ini sangat berguna di layanan Spring Boot di mana kelas utilitas menangani encoding di beberapa controller atau method service. Panggilan withoutPadding() mengembalikan instance encoder baru, sehingga Anda dapat menyimpan varian dengan padding dan tanpa padding sebagai field terpisah. Setiap panggilan ke encodeToString() atau encode() bersifat stateless โ tidak diperlukan sinkronisasi, tidak ada shared mutable state.
Kesalahan Umum
Masalah: String.getBytes() tanpa argumen charset menggunakan encoding default platform, yaitu windows-1252 di Windows, UTF-8 di sebagian besar sistem Linux, dan bervariasi di macOS. Kode yang sama menghasilkan output Base64 berbeda di mesin yang berbeda.
Solusi: Selalu teruskan StandardCharsets.UTF_8 secara eksplisit.
String text = "ะะปัั ะดะพัััะฟะฐ: prod-east"; byte[] bytes = text.getBytes(); // default platform โ tidak dapat diprediksi String encoded = Base64.getEncoder().encodeToString(bytes);
String text = "ะะปัั ะดะพัััะฟะฐ: prod-east"; byte[] bytes = text.getBytes(StandardCharsets.UTF_8); String encoded = Base64.getEncoder().encodeToString(bytes);
Masalah: Base64.getEncoder() menghasilkan karakter + dan /. Ketika ditempatkan dalam query string URL, + ditafsirkan sebagai spasi dan / sebagai pemisah path, secara diam-diam merusak nilai di sisi penerima.
Solusi: Gunakan Base64.getUrlEncoder() untuk nilai apa pun yang akan muncul dalam URL.
// Token dalam parameter query URL โ akan rusak
String token = Base64.getEncoder()
.encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;// Encoding URL-safe โ tidak ada karakter + atau /
String token = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;Masalah: Meng-encode dengan getUrlEncoder() dan men-decode dengan getDecoder() (atau sebaliknya) melempar IllegalArgumentException karena - dan _ tidak valid dalam alfabet Base64 standar, dan + dan / tidak valid dalam alfabet URL-safe.
Solusi: Selalu decode dengan decoder yang sesuai: getUrlDecoder() untuk URL-safe, getDecoder() untuk standar.
String encoded = Base64.getUrlEncoder()
.encodeToString(data);
// Nanti...
byte[] decoded = Base64.getDecoder() // decoder SALAH
.decode(encoded);
// IllegalArgumentException jika encoded mengandung - atau _String encoded = Base64.getUrlEncoder()
.encodeToString(data);
// Nanti...
byte[] decoded = Base64.getUrlDecoder() // decoder yang sesuai
.decode(encoded);Masalah: Encoder streaming men-buffer hingga 2 byte input sambil menunggu grup 3 byte lengkap. Jika Anda tidak menutup OutputStream yang membungkus, 1-4 karakter Base64 terakhir (termasuk padding) tidak pernah ditulis.
Solusi: Gunakan try-with-resources, atau panggil close() secara eksplisit pada stream yang dibungkus sebelum membaca output.
ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream b64os = Base64.getEncoder().wrap(baos); b64os.write(data); // baos.toString() TIDAK LENGKAP โ kehilangan byte terakhir
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream b64os = Base64.getEncoder().wrap(baos)) {
b64os.write(data);
} // close() mem-flush padding terakhir
String encoded = baos.toString(); // lengkapMetode Encoding Base64 โ Perbandingan
Untuk sebagian besar proyek: java.util.Base64 adalah pilihan yang tepat. Nol dependensi, sudah ada di JDK, thread-safe, dan mencakup semua tiga varian RFC 4648. Gunakan Apache Commons Codec hanya jika sudah ada di classpath Anda dan Anda membutuhkan metode validasi isBase64() atau streaming Base64OutputStream.BaseEncoding dari Guava adalah pilihan yang wajar jika proyek Anda sudah bergantung pada Guava, tetapi menambahkan dependensi 3 MB hanya untuk Base64 sulit untuk dibenarkan.
Tiga skenario, tiga pilihan: web service standar yang membutuhkan encoding Basic Auth atau JWT? Gunakan JDK. Proyek legacy yang sudah menarik Commons Codec melalui Spring atau Apache HTTP Client? Gunakan saja โ tidak ada alasan untuk memiliki dua library Base64 di classpath. Proyek yang menggunakan Guava untuk caching dan koleksi? Gunakan BaseEncoding untuk API fluent-nya yang bersih. Jangan pernah menambahkan library hanya untuk encoding Base64 โ versi JDK sudah cukup baik sejak 2014.
Jika Anda perlu memverifikasi hasil encoding dengan cepat tanpa menjalankan kode Java, tempelkan ke Base64 Encoder untuk mengonfirmasi output sesuai dengan yang dihasilkan kode Anda.
Pertanyaan yang Sering Diajukan
Bagaimana cara meng-encode String ke Base64 di Java?
Konversi string ke byte terlebih dahulu menggunakan getBytes(StandardCharsets.UTF_8), lalu teruskan array byte tersebut ke Base64.getEncoder().encodeToString(). Selalu tentukan UTF-8 secara eksplisit โ memanggil getBytes() tanpa argumen charset menggunakan default platform, yang berbeda-beda antara sistem operasi dan konfigurasi JVM.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
String payload = "grant_type=client_credentials&scope=read:metrics";
String encoded = Base64.getEncoder()
.encodeToString(payload.getBytes(StandardCharsets.UTF_8));
// Z3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMmc2NvcGU9cmVhZDptZXRyaWNzApa perbedaan antara Base64.getEncoder() dan Base64.getUrlEncoder()?
Keduanya meng-encode ke Base64, tetapi getUrlEncoder() menggunakan alfabet URL-safe yang didefinisikan dalam RFC 4648 Section 5. Alfabet ini menggantikan + dengan - dan / dengan _ sehingga output dapat muncul di URL dan nama file tanpa perlu percent-encoding. Encoder standar menggunakan + dan / yang bertentangan dengan parameter query URL dan segmen path.
byte[] data = "subject=usr_7b3c&role=admin".getBytes(StandardCharsets.UTF_8); String standard = Base64.getEncoder().encodeToString(data); // c3ViamVjdD11c3JfN2IzYyZyb2xlPWFkbWlu String urlSafe = Base64.getUrlEncoder().encodeToString(data); // c3ViamVjdD11c3JfN2IzYyZyb2xlPWFkbWlu // (sama di sini, tetapi + โ - dan / โ _ ketika karakter tersebut muncul)
Apakah java.util.Base64 sama di Java 8 dan Java 17?
Ya. API java.util.Base64 tidak berubah sejak diperkenalkan di Java 8. Kelas ini, kelas Encoder dan Decoder bertingkatnya, serta semua factory method (getEncoder, getUrlEncoder, getMimeEncoder) identik di Java 8, 11, 17, dan 21. Tidak diperlukan migrasi atau perubahan kode saat mengupgrade versi JDK.
// Kode ini dikompilasi dan dijalankan identik di Java 8 hingga Java 21+
import java.util.Base64;
import java.nio.charset.StandardCharsets;
String encoded = Base64.getEncoder()
.encodeToString("stable-api".getBytes(StandardCharsets.UTF_8));
System.out.println(encoded); // c3RhYmxlLWFwaQ==Bagaimana cara meng-encode file ke Base64 di Java?
Baca file ke dalam array byte dengan Files.readAllBytes(Path) dan teruskan ke Base64.getEncoder().encodeToString(). Untuk file besar yang tidak boleh dimuat seluruhnya ke memori, gunakan Base64.getEncoder().wrap(OutputStream) untuk melakukan streaming output yang sudah di-encode.
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
byte[] fileBytes = Files.readAllBytes(Path.of("config/tls-cert.pem"));
String encoded = Base64.getEncoder().encodeToString(fileBytes);Mengapa sun.misc.BASE64Encoder sudah deprecated?
sun.misc.BASE64Encoder adalah kelas JDK internal yang tidak pernah menjadi bagian dari API publik. Kelas ini berada di paket sun.misc, yang secara eksplisit dilarang penggunaannya oleh Oracle. Java 8 memperkenalkan java.util.Base64 sebagai pengganti resmi, publik, dan didukung. Sejak Java 9 dan sistem modul, mengakses kelas sun.misc menghasilkan peringatan atau error tergantung pada konfigurasi JDK.
// Cara lama โ JANGAN digunakan, dihapus di JDK modern // import sun.misc.BASE64Encoder; // String encoded = new BASE64Encoder().encode(data); // Cara yang benar sejak Java 8 import java.util.Base64; String encoded = Base64.getEncoder().encodeToString(data);
Bagaimana cara melakukan round-trip encode dan decode Base64 di Java?
Encode dengan Base64.getEncoder().encodeToString(bytes) dan decode dengan Base64.getDecoder().decode(encodedString). Konversi array byte hasil decode kembali ke String menggunakan new String(bytes, StandardCharsets.UTF_8). Round-trip mempertahankan data asli dengan tepat โ selama Anda menggunakan charset yang sama untuk getBytes() dan new String().
import java.util.Base64; import java.nio.charset.StandardCharsets; // Encode String original = "session_token=eyJhbGciOiJSUzI1NiJ9"; byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8); String encoded = Base64.getEncoder().encodeToString(originalBytes); // Decode byte[] decodedBytes = Base64.getDecoder().decode(encoded); String decoded = new String(decodedBytes, StandardCharsets.UTF_8); System.out.println(original.equals(decoded)); // true
Alat Terkait
- Base64 Decoder โ Decode string Base64 kembali ke teks atau bentuk biner aslinya โ operasi kebalikan dari encoding.
- URL Encoder โ Percent-encode string untuk penggunaan aman di URL โ berbeda dari encoding URL-safe Base64, tetapi sering digunakan bersama.
- JWT Decoder โ Periksa token JWT yang segmen header dan payload-nya dikodekan dengan Base64url JSON โ decode tanpa library.
- JSON Formatter โ Pretty-print payload JSON sebelum atau sesudah encoding Base64 โ berguna saat men-debug integrasi API.
Aisha is a Java engineer specialising in application security, Spring Security, and API design. She has worked on identity and access management systems, OAuth 2.0 integrations, and microservice security at scale. She writes about secure Java coding practices, token validation, cryptographic utilities, and the Spring ecosystem from a security-first perspective.
Pavel is a backend engineer with deep roots in the JVM ecosystem, working primarily with Java and Kotlin. He has extensive experience building data-intensive services and integrating third-party APIs at scale. He writes about modern Java features, the Jackson ecosystem, serialisation patterns, and practical approaches to keeping large codebases maintainable.