PTC

Guide d'internationalisation Java : traduisez les fichiers .properties avec l'IA

Configurez ResourceBundle, structurez les fichiers .properties, traduisez dans plus de 40 langues avec l'IA, puis laissez PTC (Private Translation Cloud) réviser l'application Java en cours d'exécution via des captures d'écran ou une extension de navigateur. À la fin, vous obtiendrez un JAR multilingue prêt pour la production, avec chaque langue cible vérifiée avant la sortie. Pour une présentation du service Java autonome, consultez traduire des applications Java avec l'IA.

ResourceBundle charge le bon fichier .properties à l'exécution

Le système i18n de Java s'articule autour de deux éléments. Les fichiers .properties qui stockent vos chaînes traduites, et la classe ResourceBundle qui charge le bon fichier à l'exécution en fonction de la locale de l'utilisateur.

Lorsque votre application s'exécute, ResourceBundle vérifie la locale de l'utilisateur et charge automatiquement le fichier correspondant. S'il manque une traduction, il se replie silencieusement sur le fichier par défaut. Rien ne cesse de fonctionner, mais les traductions manquantes n'apparaissent pas non plus comme des erreurs. Appel d'une chaîne dans le code :

ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.FRENCH);
String greeting = bundle.getString("welcome.message");

C'est là tout le mécanisme. Le reste du travail de localisation s'effectue dans les fichiers .properties eux-mêmes, c'est pourquoi il est important de les structurer correctement.

Configurez votre bundle de ressources avec messages_{locale}.properties

Un bundle de ressources est un ensemble de fichiers .properties qui partagent un nom de base commun. Le nom de base est la partie du nom de fichier qui précède le suffixe de la locale. C'est ce que ResourceBundle.getBundle() utilise pour trouver le bon fichier à l'exécution.

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)

Les applications plus volumineuses utilisent souvent plusieurs bundles de ressources pour rester organisées :

src/main/resources/
  messages.properties
  errors.properties
  emails.properties

Java attend un modèle de nommage spécifique : basename_language.properties, ou basename_language_COUNTRY.properties pour les variantes régionales :

messages_fr.properties      # French
messages_fr_CA.properties   # French (Canada)
messages_pt_BR.properties   # Portuguese (Brazil)

Les codes de langue suivent la norme ISO 639-1. Les codes de pays suivent la norme ISO 3166-1. Si vous utilisez le mauvais format, ResourceBundle ne trouvera pas le fichier à l'exécution.

Chargez et utilisez le bundle dans le code, avec MessageFormat pour la substitution des espaces réservés :

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"
    }
}

Pour les chaînes simples sans espaces réservés, messages.getString("key") est suffisant.

Six conventions pour rendre vos fichiers .properties prêts à traduire

Chaque ligne est une paire clé-valeur séparée par =. La façon dont vous rédigez votre fichier source affecte directement la qualité de vos traductions. Cela est vrai, que vous traduisiez manuellement ou avec un outil d'IA comme PTC.

1. Utilisez des clés claires et descriptives qui indiquent où la chaîne apparaît

Les clés doivent indiquer clairement où et comment une chaîne est utilisée. C'est important lorsque vous gérez des centaines de chaînes réparties dans plusieurs fichiers.

# Incorrect
btn1 = Submit
msg2 = Error

# Correct
form.submit.button = Submit
error.login.invalid_credentials = Invalid username or password

Ne modifiez jamais une clé une fois la traduction commencée. Modifier une clé rend la traduction existante orpheline.

2. Utilisez des espaces réservés numérotés, pas de concaténation de chaînes dans le code

Rédigez la phrase complète dans votre fichier .properties et utilisez des espaces réservés numérotés pour le contenu variable au lieu de concaténer des chaînes dans le code.

// Incorrect (in code)
"Hello, " + username + "! You have " + count + " new messages."
# Correct (in .properties)
dashboard.greeting = Hello, {0}! You have {1} new messages.

De nombreuses langues modifient l'ordre des mots et les règles d'accord. Le fait de diviser les phrases en fragments rend donc impossible une traduction correcte.

3. Gérez la pluralisation avec ChoiceFormat, ICU ou des clés à suffixe

Pour la pluralisation en Java standard, ChoiceFormat fonctionne directement dans .properties :

messages.count = {0,choice,0#no messages|1#one message|1<{0} messages}

Java traite cela à l'exécution et renvoie la bonne forme en fonction de la valeur transmise. ChoiceFormat est simple mais limité à la correspondance de plages numériques. Il ne gère pas nativement les règles de pluriel complexes.

Pour les pluriels tenant compte de la langue (one/few/many/other en polonais, les six formes de pluriel de l'arabe), utilisez MessageFormat d'ICU4J :

String pattern = "{0, plural, one {# note} other {# notes}}";
String result = new com.ibm.icu.text.MessageFormat(pattern, locale).format(new Object[]{count});

Ou encodez les pluriels sous forme de clés distinctes avec des suffixes conventionnels pour que PTC puisse générer les bonnes catégories de pluriel par langue :

notes.count.zero=No notes yet
notes.count.one={0} note
notes.count.other={0} notes

PTC génère les bonnes catégories de pluriel par langue cible. Le polonais obtient one / few / many / other. Le japonais n'obtient que other.

4. Échappez =, :, # et \ avec une barre oblique inverse

Les caractères comme =, :, # et \ ont une signification particulière dans les fichiers .properties :

  • = ou : sépare les clés des valeurs.
  • # ou ! commence un commentaire.
  • \ introduit des séquences d'échappement (comme \n pour un saut de ligne).

Échappez avec une barre oblique inverse si nécessaire :

support.link = Visit us at https\://support.example.com

5. Enregistrez les fichiers .properties en UTF-8

Enregistrez toujours les fichiers .properties en UTF-8. Sans cela, les caractères non-ASCII sont corrompus et les traductions deviennent illisibles. Historiquement, les fichiers .properties de Java étaient en ISO-8859-1, ce qui nécessitait des échappements \uXXXX pour les caractères non-ASCII. Java 9+ les lit en UTF-8 par défaut. Vérifiez donc votre version d'exécution avant de vous fier à l'UTF-8 brut.

6. Gardez tout le texte visible par l'utilisateur en dehors du code

Si une chaîne est visible par les utilisateurs, sa place est dans un fichier .properties. Les chaînes en dur ne seront pas traduites. Votre application finira par afficher un mélange de langues.

Formatez les dates, les heures, les nombres et les devises avec des helpers tenant compte de la locale

Tout ce qui doit être localisé ne se trouve pas dans un fichier .properties. Les dates, les heures, les nombres et les valeurs monétaires sont formatés dans le code à l'exécution, et il est tout aussi important de bien les traiter que vos chaînes traduites.

Dates avec 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"

Devises avec 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 €"

Utilisez toujours des formateurs tenant compte de la locale. Ne codez jamais en dur "$", les séparateurs de milliers "," ou les modèles "MM/DD/YYYY".

Intégrez ResourceBundle dans Spring Boot avec MessageSource

Spring Boot encapsule ResourceBundle dans un bean MessageSource qui s'intègre aux fonctionnalités d'i18n du framework. Il couvre également les messages de validation, les modèles Thymeleaf et la résolution de locale des requêtes web.

Configurez dans application.properties :

spring.messages.basename=messages
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=false

Placez messages.properties, messages_es.properties, etc. sous src/main/resources/.

Utilisez dans un contrôleur :

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()
        );
    }
}

Configurez le résolveur de locale pour lire à partir de l'en-tête Accept-Language ou d'un paramètre d'URL :

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);
    }
}

Maintenant, GET /greeting?name=World&lang=es renvoie la version espagnole.

Traduisez les fichiers .properties Java avec PTC en 5 étapes

  1. Démarrez un projet PTC et choisissez votre locale source (Anglais / messages.properties).
  2. Téléversez vos fichiers .properties et définissez les chemins de sortie. PTC analyse la structure clé-valeur, reconnaît les espaces réservés MessageFormat ({0}, {1}) et les modèles ChoiceFormat, et lit tous les commentaires # comme contexte pour le traducteur.
  3. Ajoutez une brève description de votre application Java et de votre public. PTC l'utilise pour traduire avec le ton et la terminologie appropriés.
  4. Choisissez les langues cibles et confirmez. L'essai couvre 20 000 mots vers 2 langues, sans carte bancaire.
  5. Téléchargez les fichiers .properties traduits depuis l'onglet Files. Un par langue, avec le bon suffixe (messages_es.properties, messages_fr.properties). Structurellement identiques à la source : mêmes clés, mêmes espaces réservés, valeurs traduites.

Déposez-les dans src/main/resources/, recompilez, et ResourceBundle.getBundle("messages", locale) détecte automatiquement les nouvelles langues. L'ensemble de la configuration prend environ 5 minutes.

Automatisez la traduction Java à chaque version avec Git ou l'API PTC

Traduire une fois est simple. Maintenir les traductions à jour à mesure que votre application évolue est plus difficile. Chaque nouvelle chaîne, chaque mise à jour de texte, chaque clé supprimée doit être répercutée dans toutes les langues. PTC propose deux façons de l'automatiser.

Intégration Git. Connectez votre dépôt GitHub, GitLab ou Bitbucket à PTC. PTC surveille votre fichier .properties source pour détecter les modifications. Lorsqu'une chaîne est ajoutée ou mise à jour, PTC la traduit et renvoie les fichiers mis à jour via une merge request.

Intégration CI/CD. Si vous préférez tout conserver dans votre processus de build existant, l'API PTC vous permet de téléverser votre fichier source et de récupérer les traductions dans le cadre de votre tâche CI.

Commitez un fichier .ptc-config.yml indiquant votre fichier source et l'emplacement des traductions :

# .ptc-config.yml
source_locale: en
files:
  - file: src/main/resources/messages.properties
    output: src/main/resources/messages_{{lang}}.properties

Ajoutez ensuite l'action PTC Translate à votre flux de travail. Elle intègre une version épinglée de la CLI PTC, de sorte que votre build ne télécharge rien à l'exécution :

# .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

PTC synchronise les nouvelles chaînes sources, traduit uniquement ce qui a changé et ouvre une PR avec les fichiers messages_es.properties, messages_fr.properties mis à jour, et ainsi de suite. Pour les projets Maven et Gradle, le même processus fonctionne. PTC ne se soucie pas de votre outil de build. Les deux approches signifient que l'ajout ultérieur d'une nouvelle langue est une modification de configuration, et non un nouveau processus manuel.

Révision visuelle de la traduction de votre application Java traduite - livrez sans contrôle qualité manuel par langue

Un fichier .properties traduit est nécessaire mais pas suffisant. Que votre application Java soit un service web Spring Boot servant du HTML, une application de bureau Swing ou un outil CLI côté serveur, le résultat rendu peut présenter des problèmes qu'aucune révision au niveau des chaînes ne peut détecter :

  • Un libellé allemand qui déborde d'un bouton Swing.
  • Un message de validation en français avec la mauvaise forme grammaticale.
  • Une chaîne en dur en anglais en dehors de messageSource.getMessage() qui s'affiche non traduite.

L'AI Visual QA de PTC couvre les deux variantes d'applications Java :

  • Pour Spring Boot ou toute application Java web : installez l'extension de navigateur PTC et enregistrez un parcours guidé des pages critiques de votre application. PTC le rejoue dans chaque langue cible après chaque mise à jour de traduction.
  • Pour les applications de bureau (Swing, JavaFX), serveur (CLI) ou toute application Java sans navigateur : téléversez des captures d'écran de l'application Java en cours d'exécution dans chaque langue cible. L'IA de vision de PTC inspecte chaque écran.

Les problèmes que PTC peut corriger dans les fichiers .properties (verbe/nom, débordement de mise en page, sens erroné) sont corrigés automatiquement. Les problèmes dans votre code Java (appel messageSource.getMessage() manquant, chaîne en dur, concaténation de phrases qui devrait utiliser MessageFormat) vous sont renvoyés sous forme de prompts prêts à coller pour Cursor ou Claude Code.

Le résultat : un JAR multilingue vérifié à chaque version. Pas seulement des fichiers de propriétés traduits.

Traduisez les notes de version, les README et les e-mails clients

Vos notes de version, les README sur votre dépôt Maven interne ou GitHub, les e-mails destinés aux clients, la documentation d'assistance et les pages de wiki internes se trouvent en dehors de .properties. L'outil Paste to Translate de PTC gère ce contenu dans le même projet. Collez le texte source dans le tableau de bord PTC, choisissez les langues cibles, et récupérez des traductions qui utilisent le même glossaire et la même voix de marque que vos chaînes dans l'application.

Traduisez les données d'entreprise, les tickets d'assistance et le contenu client avec l'API PTC

Les données d'entreprise, les tickets d'assistance, les entrées de la base de connaissances et le contenu soumis par les clients nécessitent d'être traduits dès leur arrivée. L'API REST PTC traduit ce contenu à la demande avec l'authentification par jeton Bearer, en utilisant le même glossaire et la même voix de marque que vos traductions .properties.

PTC traduit votre application Java ET révise le résultat en cours d'exécution

Commencez votre essai de 30 jours - 20 000 mots vers 2 langues, sans carte bancaire. Téléversez vos fichiers .properties, obtenez des versions traduites en quelques minutes, puis téléversez des captures d'écran (ou installez l'extension de navigateur pour Spring Boot) et laissez PTC vérifier l'application en cours d'exécution.

Sur le même sujet :