Java-Internationalisierungs-Guide: .properties-Dateien mit KI übersetzen
Richten Sie ResourceBundle ein, strukturieren Sie .properties-Dateien, übersetzen Sie mit KI in über 40 Sprachen und lassen Sie die PTC (Private Translation Cloud) anschließend die laufende Java-App anhand von Screenshots oder der Browser-Erweiterung überprüfen. Am Ende erhalten Sie ein mehrsprachiges JAR, das bereit ist, veröffentlicht zu werden, wobei jede Zielsprache vor dem Release verifiziert wurde. Einen Überblick über den eigenständigen Java-Dienst finden Sie unter Java-Apps mit KI übersetzen.
ResourceBundle lädt zur Laufzeit die richtige .properties-Datei
Das i18n-System von Java baut auf zwei Dingen auf: .properties-Dateien, die Ihre übersetzten Strings speichern, und der ResourceBundle-Klasse, die basierend auf dem Locale des Benutzers zur Laufzeit die richtige Datei lädt.
Wenn Ihre App ausgeführt wird, prüft ResourceBundle das Locale des Benutzers und lädt automatisch die passende Datei. Wenn eine Übersetzung fehlt, greift es stillschweigend auf die Standarddatei zurück. Nichts schlägt fehl, aber fehlende Übersetzungen werden auch nicht als Fehler angezeigt. Aufruf eines Strings im Code:
ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.FRENCH);
String greeting = bundle.getString("welcome.message");
Das ist der gesamte Mechanismus. Der Rest der Lokalisierungsarbeit findet in den .properties-Dateien selbst statt, weshalb es wichtig ist, diese korrekt zu strukturieren.
Richten Sie Ihr Ressourcenbündel mit messages_{locale}.properties ein
Ein Ressourcenbündel ist eine Gruppe von .properties-Dateien, die einen gemeinsamen Basisnamen teilen. Der Basisname ist der Teil des Dateinamens vor dem Locale-Suffix. Anhand dieses Namens findet ResourceBundle.getBundle() zur Laufzeit die richtige Datei.
src/main/resources/
messages.properties # default (usually English)
messages_fr.properties # French
messages_de.properties # German
messages_es.properties # Spanish
messages_ja.properties # Japanese
messages_zh_CN.properties # Simplified Chinese (note underscore, not hyphen)
Größere Anwendungen verwenden oft mehrere Ressourcenbündel, um die Übersichtlichkeit zu wahren:
src/main/resources/
messages.properties
errors.properties
emails.properties
Java erwartet ein bestimmtes Benennungsmuster: basename_language.properties oder basename_language_COUNTRY.properties für regionale Varianten:
messages_fr.properties # French
messages_fr_CA.properties # French (Canada)
messages_pt_BR.properties # Portuguese (Brazil)
Sprachcodes folgen ISO 639-1. Ländercodes folgen ISO 3166-1. Die Verwendung des falschen Formats führt dazu, dass ResourceBundle die Datei zur Laufzeit nicht findet.
Laden und verwenden Sie das Bündel im Code mit MessageFormat für die Platzhalter-Ersetzung:
import java.util.Locale;
import java.util.ResourceBundle;
import java.text.MessageFormat;
public class App {
public static void main(String[] args) {
Locale locale = Locale.of("es");
ResourceBundle messages = ResourceBundle.getBundle("messages", locale);
String welcome = MessageFormat.format(
messages.getString("app.welcome"),
"My App"
);
System.out.println(welcome);
// -> "Bienvenido a My App"
}
}
Für einfache Strings ohne Platzhalter ist messages.getString("key") ausreichend.
Sechs Konventionen, die Ihre .properties-Dateien übersetzungsbereit machen
Jede Zeile ist ein Schlüssel-Wert-Paar, das durch = getrennt ist. Wie Sie Ihre Quelldatei schreiben, wirkt sich direkt auf die Qualität Ihrer Übersetzungen aus. Dies gilt unabhängig davon, ob Sie manuell oder mit einem KI-Tool wie der PTC übersetzen.
1. Verwenden Sie klare, beschreibende Schlüssel, die benennen, wo der String erscheint
Schlüssel sollten offensichtlich machen, wo und wie ein String verwendet wird. Das ist wichtig, wenn Sie Hunderte von Strings in mehreren Dateien verwalten.
# Incorrect
btn1 = Submit
msg2 = Error
# Correct
form.submit.button = Submit
error.login.invalid_credentials = Invalid username or password
Ändern Sie niemals einen Schlüssel, nachdem die Übersetzung begonnen hat. Die Änderung eines Schlüssels führt dazu, dass die bereits vorhandene Übersetzung nicht mehr zugeordnet werden kann.
2. Verwenden Sie nummerierte Platzhalter, keine String-Verkettung im Code
Schreiben Sie den vollständigen Satz in Ihre .properties-Datei und verwenden Sie nummerierte Platzhalter für variable Inhalte, anstatt Strings im Code zu verketten.
// Incorrect (in code)
"Hello, " + username + "! You have " + count + " new messages."
# Correct (in .properties)
dashboard.greeting = Hello, {0}! You have {1} new messages.
Viele Sprachen ändern die Wortstellung und die Kongruenzregeln, sodass das Aufteilen von Sätzen in Fragmente eine korrekte Übersetzung unmöglich macht.
3. Handhaben Sie die Pluralisierung mit ChoiceFormat, ICU oder Suffix-Schlüsseln
Für die Pluralisierung in Standard-Java funktioniert ChoiceFormat direkt innerhalb von .properties:
messages.count = {0,choice,0#no messages|1#one message|1<{0} messages}
Java verarbeitet dies zur Laufzeit und gibt basierend auf dem übergebenen Wert die richtige Form zurück. ChoiceFormat ist einfach, aber auf den Abgleich von Zahlenbereichen beschränkt. Komplexe Pluralregeln beherrscht es von Haus aus nicht.
Verwenden Sie für sprachspezifische Pluralformen (die polnischen Formen one/few/many/other, die sechs Formen des Arabischen) MessageFormat der ICU4J-Bibliothek:
String pattern = "{0, plural, one {# note} other {# notes}}";
String result = new com.ibm.icu.text.MessageFormat(pattern, locale).format(new Object[]{count});
Oder codieren Sie Pluralformen als separate Schlüssel mit konventionellen Suffixen, damit die PTC die richtigen Pluralkategorien pro Sprache generieren kann:
notes.count.zero=No notes yet
notes.count.one={0} note
notes.count.other={0} notes
Die PTC generiert die richtigen Pluralkategorien pro Zielsprache. Polnisch erhält one / few / many / other. Japanisch erhält nur other.
4. Escapen Sie =, :, # und \ mit einem Backslash
Zeichen wie =, :, # und \ haben in .properties-Dateien eine besondere Bedeutung:
=oder:trennt Schlüssel von Werten.#oder!startet einen Kommentar.\leitet Escape-Sequenzen ein (wie\nfür einen Zeilenumbruch).
Escapen Sie diese bei Bedarf mit einem Backslash:
support.link = Visit us at https\://support.example.com
5. Speichern Sie .properties-Dateien als UTF-8
Speichern Sie .properties-Dateien immer in UTF-8. Ohne dies werden Nicht-ASCII-Zeichen beschädigt und Übersetzungen unlesbar. Historisch gesehen waren Java-.properties-Dateien in ISO-8859-1, was \uXXXX-Escapes für Nicht-ASCII-Zeichen erforderte. Java 9+ liest sie standardmäßig als UTF-8; überprüfen Sie also Ihre Runtime-Version, bevor Sie sich auf reines UTF-8 verlassen.
6. Halten Sie jeglichen benutzerseitigen Text aus dem Code heraus
Wenn ein String für Benutzer sichtbar ist, gehört er in eine .properties-Datei. Hartcodierte Strings werden nicht übersetzt. Ihre App wird am Ende eine Mischung aus Sprachen anzeigen.
Formatieren Sie Daten, Uhrzeiten, Zahlen und Währungen mit locale-sensitiven Helpern
Nicht alles, was lokalisiert werden muss, befindet sich in einer .properties-Datei. Daten, Uhrzeiten, Zahlen und Währungswerte werden zur Laufzeit im Code formatiert, und sie richtig hinzubekommen ist genauso wichtig wie Ihre übersetzten Strings.
Daten mit DateTimeFormatter:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
LocalDate today = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.LONG)
.withLocale(Locale.of("fr"));
System.out.println(today.format(formatter));
// -> "27 mai 2026"
Währung mit NumberFormat:
import java.text.NumberFormat;
import java.util.Currency;
NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.of("de", "DE"));
formatter.setCurrency(Currency.getInstance("EUR"));
System.out.println(formatter.format(1999.99));
// -> "1.999,99 €"
Verwenden Sie immer locale-sensitive Formatierer. Hartcodieren Sie niemals "$", ","-Tausendertrennzeichen oder "MM/DD/YYYY"-Muster.
Binden Sie ResourceBundle mit MessageSource in Spring Boot ein
Spring Boot verpackt ResourceBundle in einen MessageSource-Bean, der sich in die i18n-Funktionen des Frameworks integriert. Dies deckt auch Validierungsnachrichten, Thymeleaf-Templates und die Locale-Auflösung von Web-Requests ab.
Konfigurieren Sie in application.properties:
spring.messages.basename=messages
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=false
Platzieren Sie messages.properties, messages_es.properties usw. unter src/main/resources/.
Verwenden Sie es in einem Controller:
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
@RestController
public class GreetingController {
private final MessageSource messageSource;
public GreetingController(MessageSource messageSource) {
this.messageSource = messageSource;
}
@GetMapping("/greeting")
public String greeting(@RequestParam String name) {
return messageSource.getMessage(
"app.greeting",
new Object[]{name},
LocaleContextHolder.getLocale()
);
}
}
Konfigurieren Sie den Locale-Resolver so, dass er aus dem Accept-Language-Header oder einem URL-Parameter liest:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class I18nConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
return resolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
registry.addInterceptor(interceptor);
}
}
Nun gibt GET /greeting?name=World&lang=es die spanische Version zurück.
Übersetzen Sie Java .properties-Dateien mit der PTC in 5 Schritten
- Starten Sie ein PTC-Projekt und wählen Sie Ihr Quell-Locale (Englisch /
messages.properties). - Laden Sie Ihre
.properties-Datei(en) hoch und legen Sie Ausgabepfade fest. Die PTC parst die Schlüssel-Wert-Struktur, erkenntMessageFormat-Platzhalter ({0},{1}) sowieChoiceFormat-Muster und liest alle#-Kommentare als Übersetzerkontext. - Fügen Sie eine kurze Beschreibung Ihrer Java-Anwendung und Zielgruppe hinzu. Die PTC nutzt dies, um mit der richtigen Tonalität und Terminologie zu übersetzen.
- Wählen Sie die Zielsprachen und bestätigen Sie. Die Testphase deckt 20.000 Wörter in 2 Sprachen ab, keine Kreditkarte erforderlich.
- Laden Sie die übersetzten
.properties-Dateien aus dem Tab Files herunter. Eine pro Sprache, mit dem richtigen Suffix (messages_es.properties,messages_fr.properties). Strukturell identisch mit der Quelle: gleiche Keys, gleiche Platzhalter, übersetzte Werte.
Legen Sie sie in src/main/resources/ ab, führen Sie den Build neu aus, und ResourceBundle.getBundle("messages", locale) erkennt die neuen Sprachen automatisch. Die gesamte Einrichtung dauert etwa 5 Minuten.
Automatisieren Sie die Java-Übersetzung bei jedem Release mit Git oder der PTC-API
Einmalig zu übersetzen, ist unkompliziert. Die Übersetzungen auf dem neuesten Stand zu halten, während sich Ihre Anwendung weiterentwickelt, ist schwieriger. Jeder neue String, jede Textaktualisierung, jeder entfernte Key muss in jede Sprache einfließen. Die PTC bietet zwei Möglichkeiten, dies zu automatisieren.
Git-Integration. Verbinden Sie Ihr GitHub-, GitLab- oder Bitbucket-Repository mit der PTC. Die PTC überwacht Ihre .properties-Quelldatei auf Änderungen. Wenn ein String hinzugefügt oder aktualisiert wird, übersetzt die PTC ihn und liefert die aktualisierten Dateien über einen Merge Request zurück.
CI/CD-Integration. Wenn Sie es vorziehen, alles innerhalb Ihres bestehenden Build-Prozesses zu belassen, können Sie mit der PTC-API Ihre Quelldatei hochladen und Übersetzungen als Teil Ihres CI-Jobs abrufen.
Committen Sie eine .ptc-config.yml, die Ihre Quelldatei benennt und angibt, wohin die Übersetzungen gehören:
# .ptc-config.yml
source_locale: en
files:
- file: src/main/resources/messages.properties
output: src/main/resources/messages_{{lang}}.properties
Fügen Sie dann die PTC Translate action zu Ihrem Workflow hinzu. Sie enthält eine gepinnte Version der PTC-CLI, sodass Ihr Build zur Laufzeit nichts herunterlädt:
# .github/workflows/translate.yml
name: Translate
on:
push:
branches: [main]
paths:
- 'src/main/resources/messages.properties'
workflow_dispatch: {}
jobs:
translate:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: OnTheGoSystems/ptc-action@v1
with:
api-token: ${{ secrets.PTC_API_TOKEN }}
create-pr: true
Die PTC synchronisiert die neuen Quellstrings, übersetzt nur, was sich geändert hat, und öffnet einen PR mit den aktualisierten messages_es.properties, messages_fr.properties usw. Für Maven- und Gradle-Projekte funktioniert derselbe Workflow. Für die PTC spielt Ihr Build-Tool keine Rolle. Beide Ansätze bedeuten, dass das spätere Hinzufügen einer neuen Sprache eine Konfigurationsänderung ist und kein neuer manueller Prozess.
Visuelle Übersetzungsprüfung Ihrer übersetzten Java-App – veröffentlichen Sie ohne manuelle QA pro Sprache
Eine übersetzte .properties-Datei ist notwendig, aber nicht ausreichend. Unabhängig davon, ob Ihre Java-App ein Spring Boot-Webdienst ist, der HTML ausliefert, eine Desktop-Swing-App oder ein serverseitiges CLI-Tool, kann das gerenderte Ergebnis Fehler aufweisen, die keine Prüfung auf String-Ebene erfassen kann:
- Ein deutsches Label, das bei einem Swing-Button überläuft.
- Eine französische Validierungsnachricht mit der falschen grammatikalischen Form.
- Ein hardcodierter englischer String außerhalb von
messageSource.getMessage(), der unübersetzt angezeigt wird.
Die AI Visual QA der PTC deckt beide Varianten von Java-Apps ab:
- Für Spring Boot oder jede webbasierte Java-App: Installieren Sie die PTC-Browser-Erweiterung und zeichnen Sie einen Rundgang durch die kritischen Seiten Ihrer App auf. Die PTC spielt diesen nach jedem Übersetzungsupdate in jeder Zielsprache neu ab.
- Für Desktop- (Swing, JavaFX), Server- (CLI) oder jede nicht-browserbasierte Java-App: Laden Sie Screenshots der laufenden Java-App in jeder Zielsprache hoch. Die Vision-KI der PTC prüft jeden Bildschirm.
Fehler, die die PTC in den .properties-Dateien beheben kann (Verb/Substantiv, Layout-Überlauf, falsche Bedeutung), werden automatisch behoben. Fehler in Ihrem Java-Code (fehlender messageSource.getMessage()-Aufruf, hardcodierter String, Satzverkettung, die MessageFormat verwenden sollte) kommen als einsatzbereite Prompts für Cursor oder Claude Code zurück.
Das Ergebnis: ein verifiziertes, mehrsprachiges JAR pro Release. Nicht nur übersetzte Properties-Dateien.
Übersetzen Sie Release Notes, READMEs und Kunden-E-Mails
Ihre Release Notes, READMEs in Ihrem internen Maven-Repository oder auf GitHub, kundenorientierte E-Mails, Support-Dokumentationen und interne Wiki-Seiten befinden sich außerhalb von .properties. Paste to Translate der PTC verarbeitet diese Texte im selben Projekt. Fügen Sie den Ausgangstext in das PTC-Dashboard ein, wählen Sie die Zielsprachen aus und Sie erhalten Übersetzungen zurück, die dasselbe Glossar und dieselbe Markenstimme verwenden wie Ihre In-App-Strings.
Übersetzen Sie Unternehmensdaten, Support-Tickets und Kundeninhalte mit der PTC-API
Unternehmensdaten, Support-Tickets, Knowledge-Base-Einträge und von Kunden eingereichte Inhalte müssen direkt bei ihrem Eintreffen übersetzt werden. Die PTC-REST-API übersetzt diese Inhalte bei Bedarf mit Bearer-Token-Authentifizierung und verwendet dabei dasselbe Glossar und dieselbe Markenstimme wie Ihre .properties-Übersetzungen.
Die PTC übersetzt Ihre Java-App UND prüft das laufende Ergebnis
Starten Sie Ihre 30-Tage-Testphase – 20.000 Wörter in 2 Sprachen, keine Kreditkarte erforderlich. Laden Sie Ihre .properties-Dateien hoch, erhalten Sie in wenigen Minuten übersetzte Versionen, laden Sie dann Screenshots hoch (oder installieren Sie die Browser-Erweiterung für Spring Boot) und lassen Sie die PTC die laufende App verifizieren.
Verwandte Themen:
- Java-Apps mit KI übersetzen – Service-Übersicht für Java-Teams.
- PTC-API-Referenz – REST-Endpunkte für die CI-Integration.
- KI-Software-Lokalisierung für CI/CD-Pipelines – Service-Übersicht für Entwicklerteams.