Java AOP или аннотации для i18n

#java #jsp #internationalization #annotations #aop

#java #jsp #интернационализация #аннотации #aop

Вопрос:

Я разрабатываю веб-приложение jsp, которое не должно было быть многоязычным, но теперь они хотели, чтобы оно могло изменять язык пользовательского интерфейса в зависимости от локали браузера.

Итак, реализовать i18n для меток и других фиксированных элементов достаточно просто, но существует созданная нами платформа dashboard, в которой есть несколько стандартных отчетов, заголовки столбцов и другие элементы которых тоже фиксированы, но извлекаются из базы данных, и не все из них будут переведены.

Я думал о решении этой проблемы, используя некоторые обозначения, чтобы указать, какое значение поля является переводимым элементом. Например, возможно, с использованием некоторых #{resource.bundle.key.element} обозначений.

Ну, сущности dashboards используют JPA. Итак, я хочу знать, возможно ли выполнить перевод i18n с использованием пакетов ресурсов и выполнить перевод локали после извлечения значений из базы данных без навязчивого кодирования, возможно, с использованием аннотаций или реализаций AOP.

Возможно ли такое? или есть другой подход, который я мог бы использовать?

Ответ №1:

Интернационализация является сквозной задачей и как таковая является хорошим кандидатом для AOP. С AspectJ вы можете сделать что-то вроде этого (простой, наивный пример, просто в качестве доказательства концепции):

Приложение-драйвер:

 package de.scrum_master.app;

public class Application {
    public enum Language { EN, DE, FR };

    public final Language language;

    public Application(Language language) {
        this.language = language;
    }

    public static void main(String[] args) {
        for (Language language : Language.values())
            new Application(language).printStuff();
    }

    private void printStuff() {
        System.out.println("Hello world");
        System.out.println("This error message will not be translated.");
        System.out.println("one");
        System.out.println("two");
        System.out.println("three");
        System.out.println("This error message will also not be translated.");
        System.out.println("Goodbye");
        System.out.println();
    }
}
  

Аспект перевода:

Пожалуйста, обратите внимание: материал статического перевода должен храниться в файлах свойств или около того. Я знаю, что это некрасиво таким образом.

 package de.scrum_master.aspect;

import java.util.HashMap;
import java.util.Map;

import de.scrum_master.app.Application;
import de.scrum_master.app.Application.Language;

public aspect TranslationAspect {
    private static final Map<String, Map<Language, String>> dictionary = new HashMap<>();

    static {
        Map<Language, String> translations = new HashMap<>();
        translations.put(Language.EN, "Hello world");
        translations.put(Language.DE, "Hallo Welt");
        translations.put(Language.FR, "Bonjour tout le monde");
        dictionary.put("Hello world", translations);
        translations = new HashMap<>();
        translations.put(Language.EN, "Goodbye");
        translations.put(Language.DE, "Auf Wiedersehen");
        translations.put(Language.FR, "Au revoir");
        dictionary.put("Goodbye", translations);
        translations = new HashMap<>();
        translations.put(Language.EN, "one");
        translations.put(Language.DE, "eins");
        translations.put(Language.FR, "un");
        dictionary.put("one", translations);
        translations = new HashMap<>();
        translations.put(Language.EN, "two");
        translations.put(Language.DE, "zwei");
        translations.put(Language.FR, "deux");
        dictionary.put("two", translations);
        translations = new HashMap<>();
        translations.put(Language.EN, "three");
        translations.put(Language.DE, "drei");
        translations.put(Language.FR, "trois");
        dictionary.put("three", translations);
    }

    void around(Application application, String text) :
        call(* *.println(String)) amp;amp; this(application) amp;amp; args(text)
    {
        proceed(
            application,
            dictionary.get(text) == null ? text : dictionary.get(text).get(application.language)
        );
    }
}
  

Вывод на консоль:

 Hello world
This error message will not be translated.
one
two
three
This error message will also not be translated.
Goodbye

Hallo Welt
This error message will not be translated.
eins
zwei
drei
This error message will also not be translated.
Auf Wiedersehen

Bonjour tout le monde
This error message will not be translated.
un
deux
trois
This error message will also not be translated.
Au revoir
  

Наслаждайтесь!