国际化开发规范

2020年3月12日 作者 刘剑

匿名用户进网站,后台读取浏览器的默认请求头实现国际化;
匿名用户切换语种,前端需要保存到cookie 或请求头, 后台从这里实现国际化;
登录用后切换语种,需要调用后台接口,后台把语种保存到DB,后台从这里实现国际化;

1. Controller

String langtest = I18nUtil.getMessage("你好,世界");
// 输出: 你好,世界
//             hello, world

String langtest = I18nUtil.getMessage("你好{0},世界{1}", new Object[]{"吗", "啊"});
// 输出: 你好吗,世界啊
//             Are you ok,  my fans

例子

PublicController.islogin() 函数
            
String langtest = I18nUtil.getMessage("你好,世界");
langtest += "  " + I18nUtil.getMessage("你好{0},世界{1}", new Object[]{"吗", "啊"});

请求
http://customer.parcels.tech:8022/public/v1/subject/isLogin

枚举类型国际化

返回到页面的Dto里面属性直接使用枚举类型,不做任何处理,框架会自动翻译后另加一个字段”xxxI18n”

时间类型格式化

使用 @JSONField(format="yyyy-MM-dd HH:mm:ss") 
而不是用 jackson的注解 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

忽略

@JsonIgnore 替换成 fastjson框架的 @JSONField(serialize = false)

 

2. Job 和 JMS

(1)在 eship-customer-web 工程需要使用


    @Autowired
    private I18nServiceI  i18nService;

   i18nService.bindingI1in2Thread(userId);

具体实现为

package com.yangshan.eship.author.service.account;

/**
 * @Author: LJ
 * @Date: 2020/3/12 21:29
 * @Description: 通过user 找到 user.i18n 绑定线程 <br>
 * 提供给Job 和 JMS 国际化使用, Controller 有 I18nInterceptor 来自动绑定到线程
 */
@Transactional
@Service
public class I18nService implements I18nServiceI {

    @Autowired
    private UserDao userDao;


    @Override
    public void bindingI1in2Thread(String userId) {
        User user = userDao.findOne(userId);

        this.bindingI1in2Thread(user);
    }

    @Override
    public void bindingI1in2Thread(User user) {
        String i18n = user.getI18n();

        if (StringUtils.isNotBlank(i18n)) {
            I18nUtil.setLang(i18n);
        }
    }
}

(2)在 eship-export-data 工程需要使用


    @Autowired
    private I18nBusiness  i18nBusiness;

   i18nBusiness.bindingI1in2Thread(userId);

实现

package com.yangshan.exportData.business.account;

/**
 * @Author: LJ
 * @Date: 2020/3/12 21:29
 * @Description: 通过user 找到 user.i18n 绑定线程 <br>
 * 提供给Job 和 JMS 国际化使用, Controller 有 I18nInterceptor 来自动绑定到线程
 */
@Service
public class I18nBusiness {
    @Autowired
    private UserDao userDao;

    public void bindingI1in2Thread(String userId) {
        User user = userDao.findById(userId);

        this.bindingI1in2Thread(user);
    }

    public void bindingI1in2Thread(User user) {
        String i18n = user.getI18n();

        if (StringUtils.isNotBlank(i18n)) {
            I18nUtil.setLang(i18n);
        }
    }
}