要支持国际化,需要在容器初始化的时候配置一个处理国际化的全局拦截器。比如可以使用 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!}

JFinal 国际化的更多相关文章

  1. layui模板和jfinal混合使用注意

    <!-- 列表信息展示 --> <div class="layui-row"> <table class="layui-table" ...

  2. JFinal笔记

    目录 JFinalConfig 1. configConstant() 2. configRoute() 3. configEngine 4. configPlugin 5. configInterc ...

  3. Hello Web API系列教程——Web API与国际化

    软件国际化是在软件设计和文档开发过程中,使得功能和代码设计能处理多种语言和文化习俗,在创建不同语言版本时,不需要重新设计源程序代码的软件工程方法.这在很多成熟的软件开发平台中非常常见.对于.net开发 ...

  4. JS魔法堂:不完全国际化&本地化手册 之 理論篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

  5. Struts2入门(六)——国际化

    一.前言 1.1.国际化简介 国际化是指应用程序在运行的时候,根据客户端请求来自的国家地区.语言的不同而显示不同的界面(简单说就是根据你的地区显示相关地区的语言,如果你现在在英国,那么显示的语言就是英 ...

  6. JavaWeb的国际化

    国际化 1.国际化开发概述 1.1.软件的国际化 软件开发时,要使它能同时应对世界不同地区和国家的方法,并针对不同地区和国家的方法,提供相应的,符合来访者阅读习惯的页面或数据 国际化简称:i18n : ...

  7. struts2国际化

    struts2国际化 1:什么是国际化? 国际化(internationalization)是设计和制造容易适应不同区域要求的产品的一种方式.它要求从产品中抽离所有的与语言,国家/地区和文化相关的元素 ...

  8. 学习SpringMVC——国际化+上传+下载

    每个星期一道菜,这个星期也不例外~~~ 一个软件,一个产品,都是一点点开发并完善起来的,功能越来越多,性能越来越强,用户体验越来越好……这每个指标的提高都需要切切实实的做点东西出来,好比,你的这个产品 ...

  9. JS魔法堂:不完全国际化&本地化手册 之 实战篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

随机推荐

  1. [转]word2vec使用指导

    word2vec是一个将单词转换成向量形式的工具.可以把对文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,来表示文本语义上的相似度. 一.理论概述 (主要来源于http://lic ...

  2. [译]何时使用 Parallel.ForEach,何时使用 PLINQ

    原作者: Pamela Vagata, Parallel Computing Platform Group, Microsoft Corporation 原文pdf:http://download.c ...

  3. 探索模拟angular的双向绑定

    前言 本次探索的demo是基于jquery写的,毕竟jquery提供了强大的选择器,用惯了就离不开它了!angular的双向绑定实在是有点精深,本次探索只实现了文本的双向绑定. View-Model ...

  4. c语言第8次作业

    #include<stdio.h> int main() { ]={}; int m; ; ;m<;m++) { a[m]=m+; !=&&a[m]%!=) n++; ...

  5. Leetcode: Ones and Zeroes

    In the computer world, use restricted resource you have to generate maximum benefit is what we alway ...

  6. size_t 类型

    1 关于size_t定义 size_t是一种数据相关的无符号类型,它被设计得足够大以便能够内存中任意对象的大小.在cstddef头文件中定义了size_t类型,这个文件是C标准库stddef.h头文件 ...

  7. UIDatePicker日期选取器

    //定义显示日期的格式 NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init]; //NSDateFormatterMediumStyl ...

  8. JSP中文乱码总结

    大家在JSP的开发过程中,经常出现中文乱码的问题,可能一至困扰着大家,现把JSP开发中遇到的中文乱码的问题及解决办法写出来供大家参考.首先了解一下Java中文问题的由来: Java的内核和class文 ...

  9. 调用线程无法访问此对象,因为另一个线程拥有该对象 [c# wpf定时器程序报的错误]

    WPF:Dispatcher.Invoke 方法,只有在其上创建 Dispatcher 的线程才可以直接访问DispatcherObject.若要从不同于在其上创建 DispatcherObject ...

  10. C/C++之指针加减法

    C和C++中可对指针进行加减,但对其进行乘除则基本无实际意义.一般来说,对指针进行减法的前提是减数和被减数均指向同一数组.加法同理.需要注意的是,两个指针的减法,结果是两个地址之间索引变量的数目,而不 ...