webx3.x之多语言支持扩展

来源:互联网 发布:烈焰遮天全套完整源码 编辑:程序博客网 时间:2024/06/03 21:10

概述

本文讨论多言语在webx上的实现,其中提到的是多语言并非国际化,国际化需要包含的内容更多,多语言只是国际化中的一部分而已。

背景

1.新的海外业务起来,但是未完全成熟,需要不长期的多语言版本支持

2.同一个应用统一页面需要提供不同语言翻译

3.目前只是提供文案上的翻译,不提供或少量结构上的变化

思考

1.webx不在维护范围内,想东webx代码难,而且可能影响面比较大,所以排除webx代码变更,而是从工程层面入手

2.考虑到工期,不能作系统化重构,但是希望预留扩展;

问题分解

多语言本质上涉及到下面罗列的几个问题:
多语言的判别
模板的多语言化
动态提示的多语言化
js代码的多语言化
java代码的多语言化

多语言的判别

多语言是为了解决用户在访问时使用的语言,其信息来源客户端,可以通过两种方式实现:
用户自主选择
服务器自主识别

用户自主选择即埋点,即将不同语言的URL埋在页面,由用户自己选择,通过记录用户sessionId和语言的关系来传递用户语言信息,至于这个信息要放到cookie或者服务器端,基于扩展性建议放到服务器端;

服务器自主识别即通过http协议的 Accept-Language头来识别具体的语言。http 1.1协议(RFC2616)中规定Accept-Language的格式如下:

 Accept-Language = "Accept-Language" ":"                         1#( language-range [ ";" "q" "=" qvalue ] )       language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
可以根据q以及lang-region来判断客户端设置的语言,而该头信息是用户使用软件最熟悉语言,可以理解为用户的第一语言;

对比两种方式第二种剥夺了用户的选择权,举各场景一个中国的高端用户就是选择英语版本的chrome,但是其比较熟悉的语言是中文,这种用户就无法选择;

因此很多网站其实是把两种方案结合起来使用,默认给出一个语言判断,再可以提供链接给用户选择,在99%以上的情况都不需要用户处理,只有极少量用户可以自己选择;

模板的多语言化

阿里系大部分的web端代码都是webx框架,页面的结构都采用jsp、velocity或freemarker,本质上都是模板这些模板包含页面的主题框架样式以及js的引用;

考虑到模板代码的里面比较混杂,但是整体结构又比较稳定,因此可以分析不同语言的模板,分离方式如下:

filename_lang-region.vm

通过lang-region来区分不同语言版本,模板匹配方式如下:

filename_lang-region.vm -> filename_lang.vm -> filename.vm

这样可以直接分离不同的模板

动态提示的多语言化

动态提示大部分都是java代码中,但是这里要单独拎出的原因是笔者认为这部分代码是可以自成一体;我们可以对返回结果作不同的编码,比如采用enum(枚举实现);

通过不同的枚举以及当前用户选择语言区域来判断具体提示的内容;笔者已经实现这部分功能可以参考笔者的代码库(https://programmer-tools.googlecode.com),这样编写代码过程中只需要关注enum code,在功能编写完成后再将不同语言的提供通过配置文件填写上去

js代码的多语言化

在富客户端的影响下,越来越多的程序处理使用js来简化服务器端处理,处理方式主要有几块:越界判断提示、动态图层显示;

越界判断提示有些直接通过代码逻辑写入到js文件中,有些通过后端ajax获取文案;后者不需要js处理,前者需要

动态图层显示一般采用见图层放入到m模板,通过控制变量作显示和隐藏;

基于以上,个人考虑如下:

1.分离js中语言逻辑和文案提示

2.对于引入的文案提示内容采用动态渲染具体文案的URL,vm模板作

java代码的多语言化

这个主要是screen、action代码如何做到将多语言版本的vm整合起来,考虑到webx代码结构,可以通过<renderTemplate />作为切入点,自己实现renderI18NTemplate,实现里面的String getScreenTemplate(String target),String getLayoutTemplate(String target)方法,将多语言功能加入到其中,当然还有其他点,可以通过修改mappingRuleService.getMappedName实现来根本解决。

概要设计

梳理以上内容,可以简化如下:
1.扩展一个valve作多语言信息注入,通过head和session-lang判断将结果存入到threadlocal,上下文使用
2.实现自己的renderTemplate,解决vm模板的多语言版本加载
3.实现result的多语言映射enum+lang-----显示内容
4.js分离文案和功能代码,业务代码的通用逻辑可以放到vm或者js中
5.vm引入多语言版本的页面