简介
公司近期要做国际化,子系统比较多,所以想做一个单独的可配置化的国际化服务组件,其他子系统到时候直接引用或者进行简单修改即可使用,由于本人属于后端开发,故前端开发并不是特别了解,该方案是在跟前后端商量后定的一种方案,通过也是在Key-Val的基础上进行设计的。
表-概述
**语言表 **:顾名思义,每增加一种语言就添加一条相对应的语言数据。
虚拟系统表:子系统比较多,业务比较负责,元素各不相同,系统表区分Key元素归属那个子系统,后期容易维护。
Key表:是某一个系统的元素,可以是一句话一个词语,主要是前端页面通过该Key唯一去获取对应的Val值。
Val表:是某一个系统元素(Key)对应的语言值,一个Key可能有多种语言,即Key-Val 一对多。
表结构
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for tb_international_app
-- ----------------------------
DROP TABLE IF EXISTS `tb_international_app`;
CREATE TABLE `tb_international_app` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
`app_name` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '中文名称 例如:商品服务',
`status` int(1) DEFAULT NULL COMMENT '状态 0 生效 1 失效',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Table structure for tb_international_key
-- ----------------------------
DROP TABLE IF EXISTS `tb_international_key`;
CREATE TABLE `tb_international_key` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
`key_name` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名称 例如:提交',
`key_attribute` int(1) DEFAULT NULL COMMENT '属性 例如:0”公有“,1私有',
`key_type` int(2) DEFAULT NULL COMMENT '类型 例如:1 前端控件类型 2.后端提示类型3.后端提示值类型',
`app_id` bigint(10) DEFAULT NULL COMMENT ' 服务主键 属性为私有时不可为空',
`status` int(1) DEFAULT NULL COMMENT '状态 0生效1失效',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `app_id` (`app_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Table structure for tb_international_val
-- ----------------------------
DROP TABLE IF EXISTS `tb_international_val`;
CREATE TABLE `tb_international_val` (
`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
`val_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名称 例如:提交,submit',
`val_langeuage_id` bigint(10) DEFAULT NULL COMMENT '语言主键 例如:中文主键,英文主键',
`val_key_id` bigint(10) DEFAULT NULL COMMENT 'key主键',
`status` int(1) DEFAULT NULL COMMENT '状态 0生效1失效',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `val_key_id` (`val_key_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=191 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- ----------------------------
-- Table structure for tb_language
-- ----------------------------
DROP TABLE IF EXISTS `tb_language`;
CREATE TABLE `tb_language` (
`id` bigint(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`lang_name` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '语言名称 例如:EngLish',
`lang_ename` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`status` int(1) DEFAULT NULL COMMENT '状态 0 生效 1 失效',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
维护界面
维护列表界面 修改界面列表是通过动态列进行展示的,有几种语言就展示多少列,如果语言多了,该方式无法全部展示,目前我们最多六七个语言,就先这样用了。
这样即可通过配置的方式对元素进行维护。前端到时候将元素Key(TMHD0001)元素提交到后端,后端将对应语言进行返回,然后前端展示即可。
后端
后端有两方面需要注意
1. 业务警告异常国际化提示处理
提示信息,跟前端一样,通过Key读取对应的语言Val,然后提示即可。
2.@Validated 验证提示国际化处理
这个我是通过全局异常捕获进行处理的
代码
/**
* @ClassName GlobalExceptionHandler
* @Description TODO
* @Author gaoleijie
* @Date 2019/4/12 13:16
**/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@Value("${spring.application.name}")
private String appName;
@Autowired
private IntegrateClient integrateClient;
/**
* 验证异常
*
* @param e
* @return
* @throws MethodArgumentNotValidException
*/
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseBody
public XLResponse handleMethodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
log.info("request:{}", JSONObject.toJSONString(e));
List<FieldError> errors = bindingResult.getFieldErrors();
FieldError error = errors.get(0);
XLBaseResponse<String> res = integrateClient.getLanguageValInfo(new IntegrateClientRequest(error.getDefaultMessage(), LanguageUtils.getLanguageByHeaders(), null));
XLResponse response = new XLResponse();
Status status = new Status();
status.setTime(new Date().getTime());
status.setReturnCode("9999");
status.setServiceCode(appName);
status.setMessage("param error");
status.setPath(request.getServletPath());
if (res.isOk()) {
status.setDescription(res.getBody());
} else {
status.setDescription("请求参数验证出错");
}
response.setOk(false);
response.setStatus(status);
return response;
}
}
结束语
到此,国际化大概思路已经设计完毕了,本文章不做权威思考,只是自己的设计思路,网上有通过程序中的标签、提示等信息放在资源文件中,然后程序需要支持哪些国家、语言环境,就对应提供相应的资源文件。资源文件是key-value对,每个资源文件中的key是不变的,但value则随不同国家、语言改变,这也是一种思路具体可参考# JAVA实现国际化
网友评论