张 舒
(北京全路通信信号研究设计院集团有限公司,北京 100070)
目前越来越多的项目有了国际化需求,国际化主要是指根据语言选择,显示符合不同国家阅读习惯的页面和数据。国际化功能不仅需要将前台界面固定使用的文本元素进行翻译,对于程序动态产生的数据也需要进行翻译展示。针对固定文本信息的翻译,可以使用通用的i18n组件,根据用户当前选择语言类型,从语言配置文件中提取相应的内容。后台数据的翻译功能,目前主流方案主要有以下两种。
使用翻译网站提供的在线翻译api。这种方式不需要自备翻译数据集,方便灵活。但是当需要前后台交互并涉及到业务逻辑时,虽然可以将前台输入内容进行反向翻译统一成同一种语言内容,但是无法保证传递给逻辑业务数据内容的唯一可识别性。因此该方法仅适用于只展示动态数据,不对动态数据进行业务逻辑的情况。此外,正常网络访问也是使用此方法的必备条件。
构建数据字典,包括键值及对应的翻译语言内容。前后台交互及后台业务使用键值,前台显示时使用翻译内容。此方案完美解决了输入内容唯一可识别的需求,但是需要将待翻译的字段扩展为键值和翻译内容两个字段。这种方式要在程序设计时就考虑进去,如果是在业务开发完成或部分完成后增加,需要重新梳理并修改前后台数据结构,增大了开发工作量。
基于以上情况,因此需要设计一种易于配置并且具有高可复用性的框架实现动态数据翻译工作。
动态数据翻译框架设计如图1所示。
图1 翻译框架设计Fig.1 Translation framework design
此框架设计遵循分层原则,划分不同层的功能职责。其中Aspect用于对请求的参数及返回值拦截,调用翻译服务进行字段翻译更新数据内容;Service层(服务层)提供翻译服务,承担该框架的主要业务;Dao层(数据访问层)实现数据持久化功能,与数据源交互。框架内默认设置翻译服务包括中文、英文,如需扩展语言类型,使用时需要填写在配置文件中并更新数据库结构及内容。此功能是通过使用Cglib动态扩展java类及其接口实现。应用此框架,后台接收到请求后的运行时序如下。
1)解析请求的语言类型;
2)具有入参翻译标签的方法进行入参结构扫描,国际化功能处理成统一可识别键值;
3)核心业务逻辑处理;
受胎率用SPSS19.0统计软件进行卡方检验,精子活率和精子顶体完整率用单因素方差分析,结果用“平均值±标准差”表示。P<0. 05表示差异显著,P>0. 05表示差异不显著。
4)具有返回值翻译标签的方法进行返回值结构扫描,国际化功能处理成翻译后的内容;
5)返回替换翻译值后的响应内容。
应用此方案,基于动态数据翻译的请求http请求过程如图2所示,对于B/S架构的前台而言,仅需在http请求头中增加语言类型属性。
图2 http请求过程Fig.2 HTTP request process
此方案的优点如下。
1)对于已存在的项目进行国际化功能添加时,不会变动原有数据结构,与业务解耦。
2)使用注解标注需要翻译的接口、翻译类型(正向翻译/反向翻译)以及待翻译字段,使用AOP进行请求拦截和翻译织入,可以缩减代码,控制开发成本。
3)对于需要增扩翻译的语言种类和语言内容,可以动态扩展字典表并进行文件配置,无需增添代码。
动态数据翻译框架与已有程序的结构兼容情况如图3所示。
图3 翻译框架兼容Fig.3 Compatibility of translation framework
动态数据翻译框架搭建步骤如下。
1) 建立数据表,内容包括键值、需要翻译的语言类型,比如中文、英文。其中键值是标记翻译内容的唯一后台通用语言,用于在后台服务中进行数据交换和数据存储。
2) 翻译字典查询业务,提供正向翻译和反向翻译功能。正向翻译是指输入键值和语言种类,返回对应的语言内容;反向翻译是指输入翻译内容和语言种类,返回唯一键值。语言种类包括中文、英文、以及自定义的语言类型。对于后者,程序读取配置文件并通过Cglib自动进行装配,读取数据源数据提供对应的翻译功能。
3)自定义注解TranslateRequest,Translate Response和Translate。其中TranslateRequest标记需要对入参进行反向翻译的接口,Translate Response标记需要对返回值进行翻译的接口,Translate标记结构体中需要参与翻译的字段。
4)AOP切面级别拦截接口的请求和返回值。对于请求进行拦截,根据请求头所带语言类型,将语言内容反向翻译为唯一键值,在服务中进行数据交换;对于接口返回值进行拦截,根据请求头所带语言类型,将返回内容中的唯一键值进行翻译,替换成翻译内容作为接口调用的响应内容。
1)前台在http请求头增加Language字段,标记当前前台选择语言类型,作为后台接口输入参数反向翻译以及输出参数翻译的标准。
2)数据库中添加翻译字典。
3)并不是所有的接口和参数都有翻译需求,因此只为有翻译需求的接口和字段添加注解。在需要对入参进行反向翻译的接口进行TranslateRequest标记,在需要对返回值进行翻译的接口进行TranslateResponse标记,结构体中需要参与翻译的字段进行Translate标记。这样操作可以最大化减少不必要的翻译工作。
4)如果需要增扩翻译语言类型,需要在application.yml文件中以json的key-value格式写入dict字段。如:dict: "{id-ID: 'C_ID'}",其中key是前后台交互的语言类型,value是对应的数据库列名。
需要正向翻译的方法及返回值结构如图4所示。
图4 参考用例代码Fig.4 Code of reference use case
外部调用该接口,根据请求头Language字段值不同,返回内容不同,测试结果如图5所示。
图5 翻译测试结果Fig.5 Translation test results
本文设计了一种动态数据翻译框架,可以应用于有翻译需求的软件开发,尤其适用于增量式开发和有前后台交互需求的情况。借助AOP技术实现国际化翻译工作与核心业务的分离,使用注解方式提高框架的易用性和可复用性。通过使用本框架,可以有效提高系统的开发效率,降低人力和时间成本。该方案已经应用于海外铁路的信息化产品中并且使用效果良好,希望本框架可以为更多具有多语言动态数据翻译需求的项目提供服务或设计思路。