JFinal 国际化

要支持国际化,需要在容器初始化的时候配置一个处理国际化的全局拦截器。比如可以使用 com.jfinal.i18n.I18nInterceptor

配置拦截器:

public class MppConfig extends JFinalConfig {
    /**
     * 配置全局拦截器    GlobalInterceptor
     */
    public void configInterceptor(Interceptors me) {
          me.add(new I18nInterceptor());
    }
} 

action 请求被拦截,进入 intercept 处理:

public class I18nInterceptor implements Interceptor {
   
   
private String localeParaName = "_locale" ;
   
private String resName = "_res" ;
   
private boolean isSwitchView = false ;
   
   
public I18nInterceptor() {
    }
   
   
public I18nInterceptor(String localeParaName, String resName) {
       
if (StrKit.isBlank(localeParaName))
           
throw new IllegalArgumentException("localeParaName can not be blank." );
       
if (StrKit.isBlank(resName))
           
throw new IllegalArgumentException("resName can not be blank." );
       
       
this.localeParaName = localeParaName;
       
this.resName = resName;
    }
   
   
public I18nInterceptor(String localeParaName, String resName, boolean isSwitchView) {
       
this (localeParaName, resName);
       
this.isSwitchView = isSwitchView;
    }

   
// ...
   
    /**
    * Return the baseName, which is used as base name of the i18n resource file.
   
*/
    protected String getBaseName() {
       
return I18n.defaultBaseName;
    }
   
   
/**
    * 1: use the locale from request para if exists. change the locale write to the cookie
    * 2: use the locale from cookie para if exists.
    * 3: use the default locale
    * 4: use setAttr(resName, resObject) pass Res object to the view.
   
*/
    public void intercept(Invocation inv) {
        Controller c
= inv.getController();
        String localeParaName
= getLocaleParaName();
        String locale
= c.getPara(localeParaName);
       
       
if (StrKit.notBlank(locale)) {    // change locale, write cookie
            c.setCookie(localeParaName, locale, Const.DEFAULT_I18N_MAX_AGE_OF_COOKIE);
        }
       
else {                            // get locale from cookie and use the default locale if it is null
            locale = c.getCookie(localeParaName);
           
if (StrKit.isBlank(locale))
                locale
= I18n.defaultLocale;
        }
       
       
if (isSwitchView) {
            switchView(locale, c);
        }
       
else {
            Res res
= I18n.use(getBaseName(), locale);
            c.setAttr(getResName(), res);
        }
       
        inv.invoke();
    }
   
   
/**
    * 在有些 web 系统中,页面需要国际化的文本过多,并且 css 以及 html 也因为际化而大不相同,
    * 对于这种应用场景先直接制做多套同名称的国际化视图,并将这些视图以 locale 为子目录分类存放,
    * 最后使用本拦截器根据 locale 动态切换视图,而不必对视图中的文本逐个进行国际化切换,省时省力。
   
*/
    public void switchView(String locale, Controller c) {
        Render render
= c.getRender();
       
if (render != null ) {
            String view
= render.getView();
           
if (view != null ) {
               
if (view.startsWith("/" ))
                    view
= "/" + locale + view;
               
else
                    view
= locale + "/" + view;
               
                render.setView(view);
            }
        }
    }
}

根据地区不同得到 local 是不同的(比如中国大陆是 zh_CN,香港是 zh_HK,美国是 en-US),而 getBaseName() 是不变的即 i18n,将 local 和 baseName 进行拼接就能得到资源文件的名字,并对 Res 进行实例化。

controller.setAttr("_res" , res);

国际化资源文件

i18n_zh_CN.properties

msg=\u4F60\u597D{0}, \u4ECA\u5929\u662F{1}

i18n_en_US.properties

msg=Hello {0}, today is{1}.

Freemarker 展现:

${_res.msg!}

----- End -----

猜你喜欢

转载自www.linuxidc.com/Linux/2016-09/135256.htm
今日推荐