PTC

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

Configurez ResourceBundle, structurez vos fichiers .properties, traduisez-les dans plus de 40 langues par IA, puis laissez PTC (Private Translation Cloud) relire l'application Java en cours d'exécution via des captures d'écran ou une extension de navigateur. À la fin, vous disposerez d'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 au moment de l'exécution

Le système d'i18n de Java repose sur deux éléments : les fichiers .properties qui stockent vos chaînes traduites, et la classe ResourceBundle qui charge le bon fichier au moment de 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. Si une traduction est manquante, il se rabat silencieusement sur le fichier par défaut. Rien ne casse, mais les traductions manquantes n'apparaissent pas non plus comme des erreurs. Voici comment appeler une chaîne dans le code :

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

C'est l'ensemble du mécanisme. Le reste du travail de localisation se déroule dans les fichiers .properties eux-mêmes, c'est pourquoi il est crucial de les structurer correctement.

Configurez votre Resource Bundle avec messages_{locale}.properties

Un resource bundle est un ensemble de fichiers .properties qui partagent un nom de base commun. Le nom de base est la partie du nom de fichier située avant le suffixe de la locale. C'est ce que ResourceBundle.getBundle() utilise pour trouver le bon fichier au moment de 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 resource bundles pour rester organisées :

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

Java attend un schéma 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. L'utilisation d'un format incorrect empêchera ResourceBundle de trouver le fichier au moment de 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") suffit.

Six conventions pour rendre vos fichiers .properties prêts pour la traduction

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 s'applique que vous traduisiez manuellement ou avec un outil d'IA comme PTC.

1. Utilisez des clés claires et descriptives qui indiquent l'emplacement de la chaîne

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

# Incorrect
btn1 = Submit
msg2 = Error

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

Ne changez jamais une clé après le début de la traduction. 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 ; diviser les phrases en fragments rend donc une traduction correcte impossible.

3. Gérez la pluralisation avec ChoiceFormat, ICU ou des suffixes de clés

Pour la pluralisation en Java standard, ChoiceFormat fonctionne directement à l'intérieur des fichiers .properties :

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

Java traite cela au moment de l'exécution et renvoie la forme correcte 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 l'arabe), utilisez le 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});

Vous pouvez également encoder les pluriels sous forme de clés distinctes avec des suffixes conventionnels afin 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 un antislash

Les caractères tels que =, :, #, 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 une nouvelle ligne).

Échappez-les avec un antislash 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 Java étaient en ISO-8859-1, nécessitant 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 compter sur l'UTF-8 brut.

6. Gardez tout texte destiné à l'utilisateur hors du code

Si une chaîne est visible par les utilisateurs, sa place est dans un fichier .properties. Les chaînes codées 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 assistants tenant compte de la locale

Tout ce qui doit être localisé ne réside pas dans un fichier .properties. Les dates, les heures, les nombres et les valeurs monétaires sont formatés dans le code au moment de l'exécution, et leur exactitude importe autant que celle de 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 schémas "MM/DD/YYYY".

Intégrez ResourceBundle dans Spring Boot avec MessageSource

Spring Boot enveloppe 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 la locale des requêtes web.

Configuration 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/.

Utilisation 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 l'en-tête Accept-Language ou 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);
    }
}

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

Traduire des fichiers .properties Java avec PTC en 5 étapes

  1. Lancez un projet PTC et choisissez votre locale source (anglais / messages.properties).
  2. Téléchargez votre ou 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 schémas 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 gratuit couvre 20.000 mots dans 2 langues, sans carte bancaire.
  5. Téléchargez les fichiers .properties traduits depuis l'onglet Fichiers de ressources. Un par langue, avec le suffixe approprié (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 au fur et à mesure de l'évolution de votre application est plus difficile. Chaque nouvelle chaîne, chaque mise à jour de texte, chaque clé supprimée doit être répercutée dans chaque langue. PTC propose deux manières d'automatiser cela.

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

Intégration CI/CD. Si vous préférez tout garder au sein de votre processus de build existant, l'API de PTC vous permet de télécharger votre fichier source et de récupérer les traductions dans le cadre de votre job CI :

# .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 synchronise les nouvelles chaînes sources, ne traduit que ce qui a changé et ouvre une PR avec les fichiers messages_es.properties, messages_fr.properties, etc. mis à jour. Pour les projets Maven et Gradle, le même flux fonctionne. PTC ne se soucie pas de votre outil de build. Ces deux approches signifient que l'ajout d'une nouvelle langue ultérieurement est une simple modification de configuration, et non un nouveau processus manuel.

Relecture visuelle des traductions de votre application Java — 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 relecture au niveau des chaînes ne peut détecter :

  • Un libellé allemand qui dépasse d'un bouton Swing.
  • Un message de validation français avec une forme grammaticale incorrecte.
  • Une chaîne anglaise codée en dur en dehors de messageSource.getMessage() qui s'affiche non traduite.

L'AI Visual QA de PTC couvre les deux types 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 le bureau (Swing, JavaFX), le serveur (CLI) ou toute application Java hors navigateur : téléchargez des captures d'écran de l'application Java en cours d'exécution dans chaque langue cible. L'IA visuelle de PTC inspecte chaque écran.

Les problèmes que PTC peut corriger dans les fichiers .properties (verbe/nom, débordement de mise en page, contresens) sont corrigés automatiquement. Les problèmes dans votre code Java (appel messageSource.getMessage() manquant, chaîne codée en dur, concaténation de phrases qui devrait utiliser MessageFormat) vous sont renvoyés sous forme de prompts prêts à être collés 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 fichiers README et les e-mails clients

Vos notes de version, vos fichiers README sur votre dépôt Maven interne ou GitHub, vos e-mails destinés aux clients, votre documentation de support et vos pages de wiki interne vivent en dehors des fichiers .properties. L'outil Coller pour traduire de PTC gère ces textes 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 utilisant le même glossaire et la même voix de marque que vos chaînes intégrées à l'application.

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

Les données d'entreprise, les tickets de support, les entrées de base de connaissances et le contenu soumis par les clients doivent être traduits à mesure qu'ils arrivent. L'API REST de PTC traduit ce contenu à la demande avec une 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 relit le résultat rendu

Commencez votre essai gratuit de 30 jours — 20.000 mots dans 2 langues, sans carte bancaire. Téléchargez vos fichiers .properties, obtenez les versions traduites en quelques minutes, puis téléchargez 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.

Voir aussi :