Frage

Ich möchte eine Datenbank zum speichern von i18n-Schlüssel/Wert-Paaren, so können wir ändern / neu laden Sie die i18n-Daten zur Laufzeit.Hat jemand dies getan?Oder hat jemand eine Idee, wie man diese umsetzen?Ich habe gelesen, mehrere threads auf, aber ich habe nicht gesehen, eine brauchbare Lösung.

Ich bin speziell bezieht sich auf etwas, das funktionieren würde mit den jstl-tags wie

<fmt:setlocale>
<fmt:bundle>
<fmt:setBundle>
<fmt:message>

Ich denke, dies beinhaltet die Verlängerung ResourceBundle, aber als ich dies versuchte ich lief in Probleme, die hatte zu tun mit der Art, wie die jstl-tags erhalten, die Ressourcen zu bündeln.

War es hilfreich?

Lösung

Sie sind nur zu Fragen, wie man speichern in UTF-8/16 Zeichen in einer DB?in mysql ist es nur eine Frage der Sicherstellung, dass Sie mit UTF8-Unterstützung und festlegen, dass als Standard, oder, indem Sie auf die Spalte oder Tabelle.Ich habe dies in oracle und mysql vor.Erstellen Sie eine Tabelle Ausschneiden und einfügen einige i18n-Daten in es und sehen, was passiert...Sie könnte bereits..

oder bin ich völlig fehlt Ihr Punkt?

edit:

deutlicher...Ich in der Regel implementieren, die eine Tabelle mit drei Spalten...Sprache, Schlüssel, Wert...wobei "Wert" enthält potentiell Fremdsprache, Wörter oder Sätze..."Sprache" enthält einige Sprache mit der Taste "Schlüssel" ist eine englische Schlüssel (d.h.login.Fehler.Passwort.dup)...Sprache und Schlüssel indiziert sind...

Ich habe dann die integrierten Schnittstellen eine Struktur wie diese, die zeigt, dass jede Taste mit all seinen übersetzungen (von Werten)...es kann Lust und enthalten die audit-trails und "dirty" - Marker und alle die anderen Sachen, die Sie aktivieren müssen übersetzer und Daten Eintrag folk, es zu nutzen..

Edit 2:

Jetzt, dass Sie Hinzugefügt, die info über die JSTL-tags, ich verstehe ein bisschen mehr...Ich habe noch nie getan, mich..aber ich fand das alte info auf theserverside...

HttpSession session = .. [get hold of the session] 
ResourceBundle bundle = new PropertyResourceBundle(toInputStream(myOwnProperties)) [toInputStream just stores the properties into an inputstream] 
Locale locale = .. [get hold of the locale]
javax.servlet.jsp.jstl.core.Config.set(session, Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle ,locale));

Andere Tipps

Ich habe endlich das arbeiten mit danb Hilfe von oben.

Dies ist meine Ressource-bundle-Klasse und ResourceBundle, Klasse Steuerung.

Ich habe diesen code von @[danb]'s.

ResourceBundle bundle = ResourceBundle.getBundle("AwesomeBundle", locale, DbResourceBundle.getMyControl());
javax.servlet.jsp.jstl.core.Config.set(actionBeanContext.getRequest(), Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, locale));

und schrieb diese Klasse.

public class DbResourceBundle extends ResourceBundle
{
    private Properties properties;

    public DbResourceBundle(Properties inProperties)
    {
        properties = inProperties;
    }

    @Override
    @SuppressWarnings(value = { "unchecked" })
    public Enumeration<String> getKeys()
    {
        return properties != null ? ((Enumeration<String>) properties.propertyNames()) : null;
    }

    @Override
    protected Object handleGetObject(String key)
    {
        return properties.getProperty(key);
    }

    public static ResourceBundle.Control getMyControl()
    {
        return new ResourceBundle.Control()
        {

            @Override
            public List<String> getFormats(String baseName)
            {
                if (baseName == null)
                {
                    throw new NullPointerException();
                }
                return Arrays.asList("db");
            }

            @Override
            public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException,
                  InstantiationException, IOException
            {
                if ((baseName == null) || (locale == null) || (format == null) || (loader == null))
                    throw new NullPointerException();
                ResourceBundle bundle = null;
                if (format.equals("db"))
                {
                    Properties p = new Properties();
                    DataSource ds = (DataSource) ContextFactory.getApplicationContext().getBean("clinicalDataSource");
                    Connection con = null;
                    Statement s = null;
                    ResultSet rs = null;
                    try
                    {
                        con = ds.getConnection();
                        StringBuilder query = new StringBuilder();
                        query.append("select label, value from i18n where bundle='" + StringEscapeUtils.escapeSql(baseName) + "' ");

                        if (locale != null)
                        {
                            if (StringUtils.isNotBlank(locale.getCountry()))
                            {
                                query.append("and country='" + escapeSql(locale.getCountry()) + "' ");

                            }
                            if (StringUtils.isNotBlank(locale.getLanguage()))
                            {
                                query.append("and language='" + escapeSql(locale.getLanguage()) + "' ");

                            }
                            if (StringUtils.isNotBlank(locale.getVariant()))
                            {
                                query.append("and variant='" + escapeSql(locale.getVariant()) + "' ");

                            }
                        }
                        s = con.createStatement();
                        rs = s.executeQuery(query.toString());
                        while (rs.next())
                        {
                            p.setProperty(rs.getString(1), rs.getString(2));
                        }
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                        throw new RuntimeException("Can not build properties: " + e);
                    }
                    finally
                    {
                        DbUtils.closeQuietly(con, s, rs);
                    }
                    bundle = new DbResourceBundle(p);
                }
                return bundle;
            }

            @Override
            public long getTimeToLive(String baseName, Locale locale)
            {
                return 1000 * 60 * 30;
            }

            @Override
            public boolean needsReload(String baseName, Locale locale, String format, ClassLoader loader, ResourceBundle bundle, long loadTime)
            {
                return true;
            }

        };
    }

Wir haben eine Datenbank-Tabelle mit Schlüssel/Sprache/Begriff, wobei der Schlüssel ist, eine n integer-und einen kombinierten Primärschlüssel zusammen mit der Sprache.

Wir sind mit Streben, so landeten wir schreiben unsere eigenen PropertyMessageResources - Implementierung ermöglicht uns, etwas zu tun wie <bean:message key="impressum.text" />.

Es funktioniert sehr gut und gibt uns die Flexibilität zu tun, dynamisches wechseln von Sprachen in der front-end-als auch die Aktualisierung der übersetzung auf die Fliegen.

Actuly was ScArcher2 erforderlich ist davids Reaktion, die nicht markiert ist, eine richtige oder hilfreich.

Die Lösung ScArcher2 Wahl zu verwenden ist imo schrecklichen mestake:) Laden ALLE übersetzungen auf einmal...in jeder größeren Anwendung seine gonna kill it.Laden tausenden von übersetzungen jeder Anfrage...

david ' s Methode wird Häufig in realen Produktionsumgebungen.Manchmal beschränken db-Aufrufe, die mit jeder Nachricht, die übersetzt werden, können Sie Gruppen erstellen übersetzungen von Thema, Funktionalität etc.Vorspannung Sie.Aber das ist etwas komplexer und kann ersetzt werden, mit guten cache-system.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top