Uitzonderingsberichten lokaliseren in Java

1. Overzicht

Uitzonderingen in Java worden gebruikt om aan te geven dat er iets mis is gegaan in een programma. Naast het gooien van de uitzondering, kunnen we zelfs een bericht toevoegen om aanvullende informatie te verstrekken.

In dit artikel maken we gebruik van de getLocalizedMessage methode om uitzonderingsboodschappen in zowel het Engels als het Frans te bieden.

2. Bronnenbundel

We hebben een manier nodig om berichten op te zoeken met een messageKey om het bericht en de Locale om te bepalen welke vertaling de waarde voor de messageKey. We zullen een eenvoudige klasse maken om abstracte toegang tot onze ResourceBundle voor het ophalen van Engelse en Franse berichtvertalingen:

openbare klasse Berichten {openbare statische String getMessageForLocale (String messageKey, locale locale) {return ResourceBundle.getBundle ("berichten", locale) .getString (messageKey); }} 

Onze Berichten klasse gebruikt ResourceBundle om de eigenschappenbestanden in onze bundel te laden, die zich in de root van ons klassenpad bevindt. We hebben twee bestanden - een voor onze Engelse berichten en een voor onze Franse berichten:

# messages.properties message.exception = Ik ben een uitzondering.
# messages_fr.properties message.exception = Je suis een uitzondering.

3. Gelokaliseerde uitzonderingsklasse

Onze Uitzondering subklasse gebruikt de standaard Locale om te bepalen welke vertaling voor onze berichten moet worden gebruikt. We krijgen de standaard Locale gebruik makend van Locale # getDefault.

Als onze applicatie op een server zou draaien, zouden we de HTTP-verzoekheaders gebruiken om het Locale te gebruiken in plaats van de standaard in te stellen. Voor dit doel maken we een constructor om een Landinstelling.

Laten we onze Uitzondering subklasse. Hiervoor zouden we beide kunnen verlengen RuntimeException of Uitzondering. Laten we verlengen Uitzondering en negeren getLocalizedMessage:

public class LocalizedException breidt Exception {private final String messageKey uit; privé uiteindelijke locale locale; openbare 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. Alles samenvoegen

Laten we een aantal eenheidstests maken om te controleren of alles werkt. We zullen tests maken voor Engelse en Franse vertalingen om te controleren of een gewoonte is geslaagd Locale op uitzondering tijdens de bouw:

@Test openbare ongeldig gegevenUsEnglishProvidedLocale_whenLocalizingMessage_thenMessageComesFromDefaultMessage () {LocalizedException localizedException = nieuwe LocalizedException ("message.exception", Locale.US); String usEnglishLocalizedExceptionMessage = localizedException.getLocalizedMessage (); assertThat (usEnglishLocalizedExceptionMessage) .isEqualTo ("Ik ben een uitzondering."); } @Test openbare leegte gegevenFranceFrenchProvidedLocale_whenLocalizingMessage_thenMessageComesFromFrenchTranslationMessages () {LocalizedException localizedException = nieuwe LocalizedException ("message.exception", Locale.FRANCE); String franceFrenchLocalizedExceptionMessage = localizedException.getLocalizedMessage (); assertThat (franceFrenchLocalizedExceptionMessage) .isEqualTo ("Je suis une exception."); }

Onze uitzondering kan de standaard gebruiken Locale ook. Laten we nog twee tests maken om de standaard te verifiëren Locale functionaliteit werkt:

@Test openbare leegte gegevenUsEnglishDefaultLocale_whenLocalizingMessage_thenMessageComesFromDefaultMessages () {Locale.setDefault (Locale.US); LocalizedException localizedException = nieuwe LocalizedException ("message.exception"); String usEnglishLocalizedExceptionMessage = localizedException.getLocalizedMessage (); assertThat (usEnglishLocalizedExceptionMessage) .isEqualTo ("Ik ben een uitzondering."); } @Test openbare leegte gegevenFranceFrenchDefaultLocale_whenLocalizingMessage_thenMessageComesFromFrenchTranslationMessages () {Locale.setDefault (Locale.FRANCE); LocalizedException localizedException = nieuwe LocalizedException ("message.exception"); String franceFrenchLocalizedExceptionMessage = localizedException.getLocalizedMessage (); assertThat (franceFrenchLocalizedExceptionMessage) .isEqualTo ("Je suis une exception."); } 

5. Voorbehoud

5.1. Loggen van Throwables

We moeten rekening houden met het logboekregistratiekader dat we gebruiken om te verzenden Uitzondering instanties naar het logboek.

Log4J, Log4J2 en Logback gebruiken getMessage om het bericht op te halen om naar de logboekaanvrager te schrijven. Als we java.util.logging, de inhoud komt uit getLocalizedMessage.

We zouden kunnen overwegen om te overschrijven getMessage aan te roepen getLocalizedMessage dus we hoeven ons geen zorgen te maken over welke logboekregistratie-implementatie wordt gebruikt.

5.2. Server-side applicaties

Wanneer we onze uitzonderingsboodschappen voor clienttoepassingen lokaliseren, hoeven we ons alleen zorgen te maken over het huidige systeem van één systeem Locale. Echter, als we uitzonderingsboodschappen willen lokaliseren in een servertoepassing, moeten we in gedachten houden dat het veranderen van de standaard Locale heeft invloed op alle verzoeken binnen onze applicatieserver.

Mochten we besluiten uitzonderingsboodschappen te lokaliseren, dan maken we een constructor op onze uitzondering om de Locale. Dit geeft ons de mogelijkheid om onze berichten te lokaliseren zonder de standaard bij te werken Locale.

6. Samenvatting

Het lokaliseren van uitzonderingsboodschappen is redelijk eenvoudig. Het enige wat we hoeven te doen is een ResourceBundle voor onze berichten, voer dan uit getLocalizedMessage in onze Uitzondering subklassen.

Zoals gewoonlijk zijn de voorbeelden beschikbaar op GitHub.