一个对搜索友好的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,例子如下。

[code]
//POJO 在hibernate mapping 是field不是properties
public class Major implements Serializable {
@DocumentId
private 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){

}

}

[/code]

Localization是个简单的annotation标签,它有四个参数,前面三个分别是langauge,country和variant,于java.util.Locale的构造参数是一样的,用于构造一个可比较的locale变量,第四个参数acquiescence用于指定某个field是否为默认显示。(default被java给占用了)。

无论我们指定了多少种语言的field,默认暴露出来的就只有subject一个属性,在getSubject中,我写了一个简单的Translator来parser匹配当前locale的field. CurrentUser是个辅助类,从ServletContext中读当前locale,如果用Spring的话,可以直接wrap
[code]
LocaleContextHolder.getLocale();
[/code]

接下来是Translator的内容,并未做什么太多事情
[code]

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 compare
if (locale.equals(new Locale(i18n.language(), i18n.country(), i18n
.variant()))) {
result = field.get(object).toString();
break;
}

// set a default value if no found
if (i18n.acquiescence() && StringUtils.isEmpty(result))
result = field.get(object).toString();
}
return result;
}
}
[/code]

利用了反射读每一个field的标签,找到适合的值返回而已。

这个方案好处是,对搜索是透明的,无须干预后台生成索引,也无须干预hibernate search的搜索过程,理论上可以满足前面提出的应用场景,请大家拍砖。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值