Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
898
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
951
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
941
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1725
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6087
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4398
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
База данных с поддержкой i18n для java web-app
Я хотел бы использовать базу данных для хранения пар ключ / значение i18n, чтобы мы могли изменять / перезагружать данные i18n во время выполнения. Кто-нибудь уже сделал это? Или у кого-нибудь есть идея, как это реализовать? Я прочитал несколько тем на эту тему, но я не видел работоспособного решения.
Я специально ссылаюсь на то, что будет работать с тегами jstl, такими как
<fmt:setlocale>
<fmt:bundle>
<fmt:setBundle>
<fmt:message>
Я думаю, что это будет включать расширение ResourceBundle, но когда я попытался это сделать, я столкнулся с проблемами, которые были связаны с тем, как теги jstl получают ресурс bundle.
Я наконец - то получил эту работу с помощью данба выше.
Это мой класс resource bundle и класс управления resource bundle.
Я использовал этот код из @[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));
и написал этот класс.
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;
}
};
}
Вы просто спрашиваете, как хранить UTF-8/16 символов в DB? в mysql это просто вопрос того, чтобы убедиться, что вы строите с поддержкой UTF8 и устанавливаете его по умолчанию или указываете его на уровне столбца или таблицы. Я уже делал это в 37 и 39 годах. Создайте таблицу, вырежьте и вставьте в нее некоторые данные i18n и посмотрите, что произойдет... возможно, вы уже готовы..
или я совсем не понимаю, о чем ты говоришь?
редактировать:
чтобы быть более откровенным... Обычно я использую таблицу из трех столбцов... язык, ключ, значение... где "value" содержит потенциально иноязычные слова или фразы... "language" содержит некоторый языковой ключ, а "key"-английский ключ (т. е. login.error.password.dup)... язык и ключ индексируются...
Затем я построил интерфейсы на такой структуре, которая показывает каждый ключ со всеми его переводами (значениями)... он может стать причудливым и включать в себя маркеры аудита trails и "dirty" и все остальное, что вам нужно, чтобы позволить переводчикам и людям ввода данных использовать его..
Правка 2:
Теперь, когда вы добавили информацию о тегах JSTL, я понимаю немного больше... Я сам никогда этого не делал.. но я нашел эту старую информацию на терверсайде ...
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));
У нас есть таблица базы данных с key/language/term, где ключ-это целое число n и является комбинированным первичным ключом вместе с языком.
Мы используем Struts, поэтому мы закончили тем, что написали свою собственную реализацию PropertyMessageResources , которая позволяет нам делать что-то вроде <bean:message key="impressum.text" /> .
Он работает очень хорошо и дает нам гибкость для динамического переключения языков в интерфейсе, а также обновления переводов на лету.
На самом деле то, что ScArcher2 нужно, - это ответ Дэвида, который не отмечен правильным или полезным.
Решение ScArcher2 выбрал для использования ИМО ужасный mestake:) загрузка ALL переводов в одно время... в любом более крупном приложении это убьет его. Загрузка тысяч переводов по каждому запросу...
метод Дэвида чаще всего используется в реальных производственных условиях. Иногда для ограничения вызовов БД, то есть при каждом переводе сообщения, можно создать группы переводов по теме, функциональности и т.д. чтобы предварительно загрузить их. Но это немного сложнее и может быть заменено хорошей системой кэширования.