Java-Internationalisierungsleitfaden: .properties-Dateien mit KI übersetzen
Richten Sie ResourceBundle ein, strukturieren Sie .properties-Dateien, übersetzen Sie in mehr als 40 Sprachen mit KI und lassen Sie dann PTC (Private Translation Cloud) die laufende Java-App über Screenshots oder eine Browser-Erweiterung prüfen. Am Ende haben Sie ein mehrsprachiges JAR, das auslieferbar ist, wobei jede Zielsprache vor der Veröffentlichung verifiziert wurde. Eine Übersicht ü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 basiert auf zwei Dingen. .properties-Dateien, die Ihre übersetzten Strings speichern, und die ResourceBundle-Klasse, die zur Laufzeit anhand der Locale des Benutzers die richtige Datei lädt.
Wenn Ihre App läuft, prüft ResourceBundle die Locale des Benutzers und lädt automatisch die passende Datei. Fehlt eine Übersetzung, greift es stillschweigend auf die Standarddatei zurück. Nichts bricht ab, aber fehlende Übersetzungen erscheinen auch nicht als Fehler. Ein String wird im Code so aufgerufen:
ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.FRENCH);
String greeting = bundle.getString("welcome.message");
Das ist der gesamte Mechanismus. Die restliche Lokalisierungsarbeit findet in den .properties-Dateien selbst statt, weshalb es darauf ankommt, sie korrekt zu strukturieren.
Richten Sie Ihr Resource Bundle mit messages_{locale}.properties ein
Ein Resource Bundle ist ein Satz von .properties-Dateien, die einen gemeinsamen Basisnamen teilen. Der Basisname ist der Teil des Dateinamens vor dem Locale-Suffix. Er ist das, was ResourceBundle.getBundle() verwendet, um zur Laufzeit die richtige Datei zu finden.
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 Resource Bundles, um die Übersicht zu behalten:
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. Das falsche Format zu verwenden bedeutet, dass ResourceBundle die Datei zur Laufzeit nicht findet.
Laden und verwenden Sie das Bundle im Code, mit MessageFormat für die Platzhalter-Substitution:
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 genügt messages.getString("key").
Sechs Konventionen, die Ihre .properties-Dateien übersetzungsbereit machen
Jede Zeile ist ein Schlüssel-Wert-Paar, getrennt durch =. Wie Sie Ihre Quelldatei schreiben, wirkt sich direkt auf die Qualität Ihrer Übersetzungen aus. Ganz gleich, ob Sie manuell oder mit einem KI-Tool wie PTC übersetzen.
1. Verwenden Sie klare, beschreibende Schlüssel, die benennen, wo der String erscheint
Schlüssel sollten deutlich machen, wo und wie ein String verwendet wird. Das ist wichtig, wenn Sie Hunderte von Strings über mehrere Dateien hinweg verwalten.
# Incorrect
btn1 = Submit
msg2 = Error
# Correct
form.submit.button = Submit
error.login.invalid_credentials = Invalid username or password
Ändern Sie einen Schlüssel nie, nachdem die Übersetzung begonnen hat. Das Ändern eines Schlüssels macht die vorhandene Übersetzung verwaist.
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. Behandeln Sie Pluralisierung mit ChoiceFormat, ICU oder Suffix-Schlüsseln
Für die Pluralisierung im 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 anhand des übergebenen Werts die richtige Form zurück. ChoiceFormat ist einfach, aber auf den Abgleich numerischer Bereiche beschränkt. Es behandelt komplexe Pluralregeln nicht von Haus aus.
Für sprachbewusste Plurale (das polnische one/few/many/other, die sechs Formen des Arabischen) verwenden Sie das MessageFormat von ICU4J:
String pattern = "{0, plural, one {# note} other {# notes}}";
String result = new com.ibm.icu.text.MessageFormat(pattern, locale).format(new Object[]{count});
Oder kodieren Sie Plurale als separate Schlüssel mit konventionellen Suffixen, damit PTC die richtigen Pluralkategorien pro Sprache generieren kann:
notes.count.zero=No notes yet
notes.count.one={0} note
notes.count.other={0} notes
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!beginnt einen Kommentar.\leitet Escape-Sequenzen ein (wie\nfür einen Zeilenumbruch).
Escapen Sie 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. Andernfalls werden Nicht-ASCII-Zeichen beschädigt und Übersetzungen unlesbar. Historisch waren Java-.properties-Dateien ISO-8859-1 und erforderten \uXXXX-Escapes für Nicht-ASCII-Zeichen. Java 9+ liest sie standardmäßig als UTF-8, prüfen Sie also Ihre Laufzeitversion, bevor Sie sich auf rohes UTF-8 verlassen.
6. Halten Sie sämtlichen benutzersichtbaren Text aus dem Code heraus
Wenn ein String für Benutzer sichtbar ist, gehört er in eine .properties-Datei. Fest codierte Strings werden nicht übersetzt. Ihre App zeigt am Ende eine Mischung aus Sprachen an.
Formatieren Sie Datum, Uhrzeit, Zahlen und Währung mit locale-bewussten Helfern
Nicht alles, was lokalisiert werden muss, lebt in einer .properties-Datei. Datums-, Uhrzeit-, Zahlen- und Währungswerte werden zur Laufzeit im Code formatiert, und sie richtig hinzubekommen ist genauso wichtig wie Ihre übersetzten Strings.
Datumsangaben 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 EUR"
Verwenden Sie immer locale-bewusste Formatierer. Codieren Sie niemals "$", ","-Tausendertrennzeichen oder "MM/DD/YYYY"-Muster fest.
Binden Sie ResourceBundle mit MessageSource in Spring Boot ein
Spring Boot umhüllt ResourceBundle mit einer MessageSource-Bean, die sich in die i18n-Funktionen des Frameworks integriert. Validierungsmeldungen, Thymeleaf-Templates, Auflösung der Locale aus Web-Anfragen.
Konfiguration 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/.
Verwendung 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);
}
}
Jetzt gibt GET /greeting?name=World&lang=es die spanische Version zurück.
Übersetzen Sie Java-.properties-Dateien mit PTC in 5 Schritten
- Starten Sie ein PTC-Projekt und wählen Sie Ihre Quell-Locale (Englisch /
messages.properties). - Laden Sie Ihre
.properties-Datei(en) hoch und legen Sie Ausgabepfade fest. PTC parst die Schlüssel-Wert-Struktur, erkenntMessageFormat-Platzhalter ({0},{1}) undChoiceFormat-Muster und liest alle#-Kommentare als Übersetzerkontext. - Fügen Sie eine kurze Beschreibung Ihrer Java-Anwendung und Ihrer Zielgruppe hinzu. PTC nutzt diese, um mit dem richtigen Ton und der richtigen Terminologie zu übersetzen.
- Wählen Sie Zielsprachen und bestätigen Sie. Die kostenlose Testphase umfasst 20.000 Wörter in 2 Sprachen, ohne Kreditkarte.
- Laden Sie übersetzte
.properties-Dateien aus dem Tab Ressourcendateien herunter. Eine pro Sprache, mit dem richtigen Suffix (messages_es.properties,messages_fr.properties). Strukturell identisch mit der Quelle: gleiche Schlüssel, gleiche Platzhalter, übersetzte Werte.
Legen Sie sie in src/main/resources/ ab, bauen Sie neu, und ResourceBundle.getBundle("messages", locale) übernimmt 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
Einmal zu übersetzen ist unkompliziert. Übersetzungen aktuell zu halten, während sich Ihre Anwendung weiterentwickelt, ist schwieriger. Jeder neue String, jede Textänderung, jeder entfernte Schlüssel muss in jede Sprache durchfließen. PTC bietet zwei Möglichkeiten, dies zu automatisieren.
Git-Integration. Verbinden Sie Ihr GitHub-, GitLab- oder Bitbucket-Repository mit PTC. PTC überwacht Ihre .properties-Quelldatei auf Änderungen. Wenn ein String hinzugefügt oder aktualisiert wird, übersetzt PTC ihn und liefert die aktualisierten Dateien über einen Pull Request zurück.
CI/CD-Integration. Wenn Sie es vorziehen, alles innerhalb Ihres bestehenden Build-Prozesses zu belassen, ermöglicht Ihnen die API von PTC, Ihre Quelldatei hochzuladen und Übersetzungen als Teil Ihres CI-Jobs abzurufen:
# .github/workflows/translate.yml
name: PTC translate
on:
push:
branches: [main]
paths:
- 'src/main/resources/messages.properties'
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trigger PTC translation
run: |
curl -X POST https://api.ptc.wpml.org/v1/projects/${{ secrets.PTC_PROJECT_ID }}/sync \
-H "Authorization: Bearer ${{ secrets.PTC_API_KEY }}"
PTC synchronisiert die neuen Quell-Strings, übersetzt nur das, was sich geändert hat, und öffnet einen PR mit den aktualisierten messages_es.properties, messages_fr.properties und so weiter. Für Maven- und Gradle-Projekte funktioniert derselbe Ablauf. PTC ist Ihr Build-Tool gleichgültig. Beide Ansätze bedeuten, dass das spätere Hinzufügen einer neuen Sprache eine Konfigurationsänderung ist, kein neuer manueller Prozess.
Visuelle Übersetzungsprüfung Ihrer übersetzten Java-App - ausliefern ohne manuelle QA pro Sprache
Eine übersetzte .properties-Datei ist notwendig, aber nicht ausreichend. Ob Ihre Java-App ein Spring-Boot-Webdienst ist, der HTML ausliefert, eine Desktop-Swing-App oder ein serverseitiges CLI-Tool, die gerenderte Ausgabe kann Probleme haben, die keine Prüfung auf String-Ebene erkennen kann:
- Eine deutsche Beschriftung, die über eine Swing-Schaltfläche hinausläuft.
- Eine französische Validierungsmeldung mit der falschen grammatikalischen Form.
- Ein fest codierter englischer String außerhalb von
messageSource.getMessage(), der unübersetzt angezeigt wird.
Die visuelle KI-Prüfung von PTC deckt beide Spielarten von Java-Apps ab:
- Für Spring Boot oder jede webbasierte Java-App: Installieren Sie die PTC-Browser-Erweiterung und zeichnen Sie einen Durchlauf der kritischen Seiten Ihrer App auf. PTC spielt ihn nach jeder Übersetzungsaktualisierung in jeder Zielsprache erneut ab.
- Für Desktop (Swing, JavaFX), Server (CLI) oder jede Nicht-Browser-Java-App: Laden Sie Screenshots der laufenden Java-App in jeder Zielsprache hoch. Die Vision-KI von PTC prüft jeden Bildschirm.
Probleme, die PTC in den .properties-Dateien beheben kann (Verb/Substantiv, Layout-Überlauf, falscher Sinn), werden automatisch behoben. Probleme in Ihrem Java-Code (fehlender messageSource.getMessage()-Aufruf, fest codierter String, Satzverkettung, die MessageFormat verwenden sollte) kommen als einfügefertige Prompts für Cursor oder Claude Code zurück.
Das Ergebnis: ein verifiziertes, mehrsprachiges JAR pro Release. Nicht nur übersetzte Property-Dateien.
Übersetzen Sie Release-Notes, READMEs und Kunden-E-Mails
Ihre Release-Notes, READMEs in Ihrem internen Maven-Repository oder auf GitHub, kundenseitige E-Mails, Support-Dokumentation und interne Wiki-Seiten leben außerhalb von .properties. Die Funktion „Einfügen zum Übersetzen" von PTC verarbeitet diesen Text im selben Projekt. Fügen Sie den Quelltext in das PTC-Dashboard ein, wählen Sie Zielsprachen und erhalten Sie Übersetzungen zurück, die dasselbe Glossar und dieselbe Markenstimme wie Ihre In-App-Strings verwenden.
Übersetzen Sie Unternehmensdaten, Support-Tickets und Kundeninhalte mit der PTC-API
Unternehmensdaten, Support-Tickets, Wissensdatenbankeinträge und von Kunden übermittelte Inhalte müssen übersetzt werden, sobald sie eintreffen. Die PTC-REST-API übersetzt diese Inhalte bei Bedarf mit Bearer-Token-Authentifizierung und verwendet dasselbe Glossar und dieselbe Markenstimme wie Ihre .properties-Übersetzungen.
Übersetzen UND prüfen Sie Ihre Java-App
Starten Sie Ihre kostenlose 30-Tage-Testphase - 20.000 Wörter in 2 Sprachen, ohne Kreditkarte. Laden Sie Ihre .properties-Dateien hoch, erhalten Sie übersetzte Versionen in Minuten, laden Sie dann Screenshots hoch (oder installieren Sie die Browser-Erweiterung für Spring Boot) und lassen Sie PTC die laufende App verifizieren.
Verwandt:
- Java-Apps mit KI übersetzen - Dienstübersicht für Java-Teams.
- PTC-API-Referenz - REST-Endpunkte für die CI-Integration.
- KI-Softwarelokalisierung für CI/CD-Pipelines - Dienstübersicht für Entwicklungsteams.