一个对搜索友好的Hibernate I18N方案请人拍砖
长久以前做18n一直靠Strurts的resource bundler的方法,从properties里读取一个个key的值来对应显示正确的语言文字,对于大部分场景这都是满足的。
但是对于有些情况,Resource bundler就不一定适合,比说产品的名称,一个很简单的例子,我的产品中文叫“钢笔,铅笔”,英文叫“pen,pencil",在搜索场景中,国内客户输入的就是“笔”--他想要钢笔铅笔的报价,国外用户可能输入“pen"--他只要钢笔的价格。那么resource bundler在这种情景下就有点力不从心。---可能方案,parser对应的properties,对应line的key读出来,然后读数据库,取信息....(也许luncene有更好的方案,不过偶不知道)。
因此我的初步解决方法是,将各国语言都存储到数据库中去,利用java 5.0的annotation标注其适用的field,例子如下。
//POJO 在hibernate mapping 是field不是propertiespublic class Major implements Serializable {@DocumentIdprivate int id = 0;@SuppressWarnings("unused")@Field(name="subject",index = Index.TOKENIZED, store = Store.NO)@Localization(language = "en", country = "US", acquiescence = true)private String subject_english = StringUtils.EMPTY;@SuppressWarnings("unused")@Field(name="subject",index = Index.TOKENIZED, store = Store.NO)@Localization(language = "zh", country = "CN")private String subject_chinese = StringUtils.EMPTY; // get/set Id 从略 public String getSubject(){ return Translator.translate(this, CurrentUser.getLocale()); } public void setSubject(String subject){ } }
LocaleContextHolder.getLocale();
import java.util.Locale;import java.lang.reflect.Field;import org.apache.commons.lang.StringUtils;public class Translator {public static String translate(Object object, Locale locale)throws IllegalAccessException {String result = StringUtils.EMPTY;for (Field field : object.getClass().getFields()) {field.setAccessible(true);Localization i18n = (Localization) field.getAnnotation(Localization.class);// construct a local for compareif (locale.equals(new Locale(i18n.language(), i18n.country(), i18n.variant()))) {result = field.get(object).toString();break;}// set a default value if no foundif (i18n.acquiescence() && StringUtils.isEmpty(result))result = field.get(object).toString();}return result;}}