Melokalkan Pesan Pengecualian di Java

1. Ikhtisar

Pengecualian di Java digunakan untuk memberi sinyal bahwa ada sesuatu yang tidak beres dalam suatu program. Selain melempar pengecualian, kami bahkan dapat menambahkan pesan untuk memberikan informasi tambahan.

Dalam artikel ini, kami akan memanfaatkan metode getLocalizedMessage untuk memberikan pesan pengecualian dalam bahasa Inggris dan Prancis.

2. Paket Sumber Daya

Kami membutuhkan cara untuk mencari pesan menggunakan messageKey untuk mengidentifikasi pesan dan Lokal untuk mengidentifikasi terjemahan mana yang akan memberikan nilai untuk messageKey . Kami akan membuat kelas sederhana untuk akses abstrak ke ResourceBundle kami untuk mengambil terjemahan pesan bahasa Inggris dan Prancis:

public class Messages { public static String getMessageForLocale(String messageKey, Locale locale) { return ResourceBundle.getBundle("messages", locale) .getString(messageKey); } } 

Kelas Messages kami menggunakan ResourceBundle untuk memuat file properti ke dalam bundel kami, yang merupakan root dari classpath kami. Kami memiliki dua file - satu untuk pesan bahasa Inggris kami dan satu lagi untuk pesan bahasa Prancis kami:

# messages.properties message.exception = I am an exception.
# messages_fr.properties message.exception = Je suis une exception.

3. Kelas Pengecualian Lokal

Subkelas Exception kami akan menggunakan Lokal default untuk menentukan terjemahan mana yang digunakan untuk pesan kami. Kami akan mendapatkan Lokal default menggunakan Lokal # getDefault .

Jika aplikasi kami berjalan di server, kami akan menggunakan header permintaan HTTP untuk mengidentifikasi Lokal yang akan digunakan alih-alih menyetel default. Untuk tujuan ini, kami akan membuat konstruktor untuk menerima Lokal.

Mari buat subclass Exception kita . Untuk ini, kami dapat memperluas RuntimeException atau Exception . Mari memperluas Exception dan mengganti getLocalizedMessage :

public class LocalizedException extends Exception { private final String messageKey; private final Locale locale; public LocalizedException(String messageKey) { this(messageKey, Locale.getDefault()); } public LocalizedException(String messageKey, Locale locale) { this.messageKey = messageKey; this.locale = locale; } public String getLocalizedMessage() { return Messages.getMessageForLocale(messageKey, locale); } } 

4. Menyatukan Semuanya

Mari buat beberapa pengujian unit untuk memverifikasi bahwa semuanya berfungsi. Kami akan membuat tes untuk terjemahan bahasa Inggris dan Prancis untuk memverifikasi kelulusan Lokal kustom ke pengecualian selama konstruksi:

@Test public void givenUsEnglishProvidedLocale_whenLocalizingMessage_thenMessageComesFromDefaultMessage() { LocalizedException localizedException = new LocalizedException("message.exception", Locale.US); String usEnglishLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(usEnglishLocalizedExceptionMessage).isEqualTo("I am an exception."); } @Test public void givenFranceFrenchProvidedLocale_whenLocalizingMessage_thenMessageComesFromFrenchTranslationMessages() { LocalizedException localizedException = new LocalizedException("message.exception", Locale.FRANCE); String franceFrenchLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(franceFrenchLocalizedExceptionMessage).isEqualTo("Je suis une exception."); }

Pengecualian kami dapat menggunakan Lokal default juga. Mari buat dua tes lagi untuk memverifikasi fungsi Lokal default berfungsi:

@Test public void givenUsEnglishDefaultLocale_whenLocalizingMessage_thenMessageComesFromDefaultMessages() { Locale.setDefault(Locale.US); LocalizedException localizedException = new LocalizedException("message.exception"); String usEnglishLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(usEnglishLocalizedExceptionMessage).isEqualTo("I am an exception."); } @Test public void givenFranceFrenchDefaultLocale_whenLocalizingMessage_thenMessageComesFromFrenchTranslationMessages() { Locale.setDefault(Locale.FRANCE); LocalizedException localizedException = new LocalizedException("message.exception"); String franceFrenchLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(franceFrenchLocalizedExceptionMessage).isEqualTo("Je suis une exception."); } 

5. Peringatan

5.1. Logging Throwable

Kami harus mengingat kerangka kerja logging yang kami gunakan untuk mengirim instance Exception ke log.

Log4J, Log4J2, dan Logback menggunakan getMessage untuk mengambil pesan yang akan ditulis ke appender log. Jika kita menggunakan java.util.logging , kontennya berasal dari getLocalizedMessage .

Kami mungkin ingin mempertimbangkan untuk mengganti getMessage untuk memanggil getLocalizedMessage sehingga kami tidak perlu khawatir tentang implementasi logging mana yang digunakan.

5.2. Aplikasi Sisi Server

Saat kami melokalkan pesan pengecualian kami untuk aplikasi klien, kami hanya perlu mengkhawatirkan tentang Lokal satu sistem saat ini . Namun, jika kita ingin melokalkan pesan pengecualian dalam aplikasi sisi server, kita harus ingat bahwa mengganti Lokal default akan mempengaruhi semua permintaan dalam server aplikasi kita.

Jika kami memutuskan untuk melokalkan pesan pengecualian, kami akan membuat konstruktor pada pengecualian kami untuk menerima Lokal . Ini akan memberi kita kemampuan untuk melokalkan pesan kita tanpa memperbarui Lokal default .

6. Ringkasan

Melokalkan pesan pengecualian cukup mudah. Yang perlu kita lakukan adalah membuat ResourceBundle untuk pesan kita, lalu mengimplementasikan getLocalizedMessage di subkelas Exception .

Seperti biasa, contoh tersedia di GitHub.