java后端国际化实现

java后端国际化实现如果你还在为国际化的问题苦恼的话 不妨往下看看 本文采取数据库去存储国际化字典 再对响应内容做全局处理 1 数据库设计 CREATE TABLE i18n dictionary key varchar 255 DEFAULT NULL COMMENT 中文内容

大家好,我是讯享网,很高兴认识大家。

如果你还在为国际化的问题苦恼的话, 不妨往下看看 ↓↓↓

本文采取数据库去存储国际化字典,再对响应内容做全局处理

1.数据库设计

CREATE TABLE `i18n_dictionary` ( `key` varchar(255) DEFAULT NULL COMMENT '中文内容', `system` varchar(255) DEFAULT NULL COMMENT '自定义程序标识,用来区分程序', `lang_en` varchar(255) DEFAULT NULL COMMENT '英语', `lang_thai` varchar(255) DEFAULT NULL COMMENT '泰文', `type` varchar(255) DEFAULT NULL COMMENT '类型 content表示json内容 key表示json的key' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

讯享网

在这里插入图片描述
讯享网

2.依赖

讯享网<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> 

3.目录展示

e&taskId=ucc21a2d4-bd13-4476-8d0b-d9951770607&title=&width=459)

4.查询sql

 / * 获取表头 * @return */ @Select("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE table_name = 'i18n_dictionary'") List<String> getI18nDictionary(); / * 根据类型获取国际化数据 * @param type * @return */ @Select("select * from i18n_dictionary where type=#{type}") List<Map<String,String>> getI18nListMap(@Param("type")String type); 

5.初始化缓存加载和全局处理

缓存类

初始加载字典缓存, 以及对字典定时刷新

讯享网import com.zsx.i18ndemo.mapper.I18nMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Component @Slf4j public class I18nDictionaryCache { 
    // 语言, 中文 对应content内容 private static Map<String, Map<String, String>> i18nContentDictionary = new HashMap<>(); // 语言, 中文, 对应json返回map的key private static Map<String, Map<String, String>> i18nKeyDictionary = new HashMap<>(); //其他, 支持自定义呗 private static Map<String, Map<String, String>> i18nHeaderDictionary = new HashMap<>(); // 外国语言转成中文用于批量导入 private static Map<String, Map<String, String>> i18nTransChineseDict = new HashMap<>(); @Autowired private I18nMapper i18nMapper; / * 初始化加载字典 */ @PostConstruct public void init() { 
    long time = System.currentTimeMillis(); initDictionary("content", i18nContentDictionary, TranTypeEnum.CN_TO_OTHER); initDictionary("key", i18nKeyDictionary, TranTypeEnum.CN_TO_OTHER); initDictionary("header", i18nHeaderDictionary, TranTypeEnum.CN_TO_OTHER); initDictionary("title", i18nTransChineseDict, TranTypeEnum.OTHER_TO_CN); log.info("初始化国际化字典信息完成,耗时:" + (System.currentTimeMillis() - time)); } / * 初始化加载字典 */ @Scheduled(fixedRate = 30000) public void refreshDictionary() { 
    long time = System.currentTimeMillis(); initDictionary("content", i18nContentDictionary, TranTypeEnum.CN_TO_OTHER); initDictionary("key", i18nKeyDictionary, TranTypeEnum.CN_TO_OTHER); initDictionary("header", i18nHeaderDictionary, TranTypeEnum.CN_TO_OTHER); initDictionary("title", i18nTransChineseDict, TranTypeEnum.OTHER_TO_CN); log.info("刷新化国际化字典信息完成,耗时:" + (System.currentTimeMillis() - time)); } / * 添加字典 */ public static void addDictionary(String locale, String key, String value, Map<String, Map<String, String>> i18nContentDictionary) { 
    Map<String, String> stringStringMap = i18nContentDictionary.computeIfAbsent(locale, k -> new LinkedHashMap<>()); stringStringMap.put(key, value); } / * 将国际化字典添加到map,(批量导入的,其他语言转成中文) * * @param type * @param i18nDictionaryType */ public void initDictionary(String type, Map<String, Map<String, String>> i18nDictionaryType, TranTypeEnum tranType) { 
    List<String> columns = i18nMapper.getI18nDictionary(); List<Map<String, String>> i18nListMap = i18nMapper.getI18nListMap(type); //这里进行一下排序,防止转换不全: 例如 添加成功 先匹配成功 ,就成了 添加success List<Map<String, String>> i18nListMapSorted = i18nListMap.stream().sorted((i, j) -> j.get("key").length() - i.get("key").length()).collect(Collectors.toList()); if (i18nListMapSorted.size() > 0 && i18nDictionaryType.size() > 0) { 
    i18nDictionaryType.clear(); } for (Map<String, String> map : i18nListMapSorted) { 
    for (String column : columns) { 
    if (column.contains("lang")) { 
    if (tranType.getValue() == 0) { 
    //其他语言做key addDictionary(column, map.get("key"), map.get(column), i18nDictionaryType); } else { 
    //中**key addDictionary(column, map.get(column), map.get("key"), i18nDictionaryType); } } } } } public static Map<String, String> getContentDictionary(String locale) { 
   return i18nContentDictionary.get(locale);} public static Map<String, String> getKeyDictionary(String locale) { 
   return i18nKeyDictionary.get(locale);} public static Map<String, String> getHeaderDictionary(String locale) { 
   return i18nHeaderDictionary.get(locale);} public static Map<String,String> getTransChineseDict(String locale){ 
   return i18nTransChineseDict.get(locale);} 
转换类型枚举
public enum TranTypeEnum { 
    CN_TO_OTHER(0,"中文作key"), OTHER_TO_CN(1,"英**key") ; private Integer value; private String remark; TranTypeEnum(int value, String remark) { 
    this.value=value; this.remark=remark; } public Integer getValue() { 
    return value; } public String getRemark() { 
    return remark; } } 
通用返回实体
讯享网@Data public class RetObj<T> { 
    int code; / * 结果描述信息 */ String msg; / * 结果对象 */ T obj; / * 扩展数据 */ Map<String, Object> extend; public RetObj(){ 
    code = 200; } public RetObj(int code, String msg, T obj, Map<String, Object> extend) { 
    super(); this.code = code; this.msg = msg; this.obj = obj; this.extend = extend; } /* * 设置为错误 * @param msg */ public void fail(String msg){ 
    code = 500; this.msg = msg; } } 
测试用户实体
@Data @NoArgsConstructor @AllArgsConstructor public class User { 
    private String name; private Integer age; private String address; private String sex; } 
全局处理
讯享网import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.zsx.i18ndemo.cache.I18nDictionaryCache; import com.zsx.i18ndemo.util.ResponseI18nUtil; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import java.util.Map; @ControllerAdvice(basePackages = "com.zsx.i18ndemo.controller") public class ResponseBodyI18nAdvice implements ResponseBodyAdvice<Object> { 
    @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { 
    return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { 
    //响应国际化内容 HttpHeaders headers = request.getHeaders(); //需要响应的语言 String locale = headers.getFirst("locale"); if(locale!=null && body!=null){ 
    Map<String, String> contentDictionary = I18nDictionaryCache.getContentDictionary(locale); if(contentDictionary!=null){ 
    JSONObject jsonObject = (JSONObject) JSON.toJSON(body); ResponseI18nUtil.jsonObjectI18n(jsonObject,contentDictionary); Map<String, String> keyDictionary = I18nDictionaryCache.getKeyDictionary(locale); //转换中文key if(keyDictionary!=null){ 
    return ResponseI18nUtil.changeJsonObj(jsonObject,keyDictionary); } return jsonObject; } } return body; } } 

6.响应帮助类

import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.zsx.i18ndemo.cache.I18nDictionaryCache; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Field; import java.util.*; public class ResponseI18nUtil { 
    / * jsonObject国际化 * * @param jsonObject * @param keyMap */ public static void jsonObjectI18n(JSONObject jsonObject, Map<String, String> keyMap) { 
    Set<String> keySet = jsonObject.keySet(); for (String key : keySet) { 
    Object obj = jsonObject.get(key); if (obj instanceof String) { 
    replaceValue(jsonObject, key, keyMap); } else { 
    if (obj instanceof JSONObject) { 
    jsonObjectI18n(jsonObject.getJSONObject(key), keyMap); } if (obj instanceof JSONArray) { 
    jsonArrayI18n(jsonObject.getJSONArray(key), keyMap); } } } } / * jsonArray国际化 * * @param jsonArray * @param keyMap */ public static void jsonArrayI18n(JSONArray jsonArray, Map<String, String> keyMap) { 
    for (int i = 0; i < jsonArray.size(); i++) { 
    Object obj = jsonArray.get(i); if (obj instanceof JSONObject) { 
    jsonObjectI18n(jsonArray.getJSONObject(i), keyMap); } if (obj instanceof JSONArray) { 
    jsonArrayI18n(jsonArray.getJSONArray(i), keyMap); } } } / * 替换value值 * * @param jsonObject * @param key * @param keyMap */ public static void replaceValue(JSONObject jsonObject, String key, Map<String, String> keyMap) { 
    String value = jsonObject.getString(key); for (Map.Entry<String, String> entry : keyMap.entrySet()) { 
    if (StrUtil.isNotBlank(key)) { 
    if (value.contains(entry.getKey())&&entry.getValue()!=null) { 
    value = value.replace(entry.getKey(), entry.getValue()); } } } jsonObject.put(key, value); } / * 国际化集合中对象的String字段 * * @param data * @throws Exception */ private static <T> void changeStringField(List<T> data, Map<String, String> keyMap) throws Exception { 
    for (T obj : data) { 
    Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { 
    if (field.getType() == String.class) { 
    field.setAccessible(true); String oldValue = (String) field.get(obj); for (Map.Entry<String, String> entry : keyMap.entrySet()) { 
    if (StrUtil.isNotBlank(oldValue)) { 
    if (oldValue.contains(entry.getKey())&&entry.getValue()!=null) { 
    oldValue = oldValue.replace(entry.getKey(), entry.getValue()); } } } field.set(obj, oldValue); } } } } / * 国际化对象集合中的String字段 * * @param data * @throws Exception */ public static <T> void i18nFormatExportData(List<T> data) throws Exception { 
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String locale = request.getHeader("locale"); if (StrUtil.isNotBlank(locale)) { 
    Map<String, String> keyMap = I18nDictionaryCache.getContentDictionary(locale); if(keyMap==null){ 
    return; } changeStringField(data, keyMap); } } / * 国际化对象集合中的String字段 * * @param titleHeaders * @throws Exception */ private static void i18nFormatExportHeader(Map<String, String> titleHeaders) { 
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String locale = request.getHeader("locale"); if (StrUtil.isNotBlank(locale)) { 
    Map<String, String> keyMap = I18nDictionaryCache.getHeaderDictionary(locale); if(keyMap==null){ 
    return; } for (Map.Entry<String, String> entry : titleHeaders.entrySet()) { 
    String oldValue = entry.getValue(); for (Map.Entry<String, String> dictEntry : keyMap.entrySet()) { 
    if (oldValue.contains(dictEntry.getKey())&&dictEntry.getValue()!=null) { 
    oldValue = oldValue.replace(dictEntry.getKey(), dictEntry.getValue()); } } titleHeaders.put(entry.getKey(),oldValue); } } } public static String[] i18nFormatExportHeader(String[] titleHeaders) { 
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String locale = request.getHeader("locale"); if (StrUtil.isNotBlank(locale)) { 
    List<String> titleHeaderList = new ArrayList<>(); Map<String, String> keyMap = I18nDictionaryCache.getHeaderDictionary(locale); for (String oldValue : titleHeaders) { 
    for (Map.Entry<String, String> dictEntry : keyMap.entrySet()) { 
    if (oldValue.contains(dictEntry.getKey())&&dictEntry.getValue()!=null) { 
    oldValue = oldValue.replace(dictEntry.getKey(), dictEntry.getValue()); } } titleHeaderList.add(oldValue); } return titleHeaderList.toArray(new String[titleHeaderList.size()]); } return titleHeaders; } public static String[] i18nFormatExportHeader(String[] titleHeaders,String locale) { 
    if (StrUtil.isNotBlank(locale)) { 
    List<String> titleHeaderList = new ArrayList<>(); Map<String, String> keyMap = I18nDictionaryCache.getHeaderDictionary(locale); for (String oldValue : titleHeaders) { 
    for (Map.Entry<String, String> dictEntry : keyMap.entrySet()) { 
    if (oldValue.contains(dictEntry.getKey())&&dictEntry.getValue()!=null) { 
    oldValue = oldValue.replace(dictEntry.getKey(), dictEntry.getValue()); } } titleHeaderList.add(oldValue); } return titleHeaderList.toArray(new String[titleHeaderList.size()]); } return titleHeaders; } public static String i18nFormatExportFileName(String fileName){ 
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String locale = request.getHeader("locale"); if (StrUtil.isNotBlank(locale) && null != fileName) { 
    Map<String, String> keyMap = I18nDictionaryCache.getHeaderDictionary(locale); for (Map.Entry<String, String> dictEntry : keyMap.entrySet()) { 
    if (null != dictEntry.getKey() && dictEntry.getKey().equals(fileName)) { 
    return dictEntry.getValue().replaceAll(" ", ""); } } } return fileName; } / * key的国际化 * * @param jsonObj * @param keyMap * @return */ public static JSONObject changeJsonObj(JSONObject jsonObj, Map<String, String> keyMap) { 
    JSONObject resJson = new JSONObject(); Set<String> keySet = jsonObj.keySet(); for (String key : keySet) { 
    String resKey = keyMap.get(key) == null ? key : keyMap.get(key); try { 
    Object obj= jsonObj.get(key); if(obj instanceof String){ 
    resJson.put(resKey, jsonObj.get(key)); } else { 
    JSONObject jsonobj1 = jsonObj.getJSONObject(key); resJson.put(resKey, changeJsonObj(jsonobj1, keyMap)); } } catch (Exception e) { 
    try { 
    JSONArray jsonArr = jsonObj.getJSONArray(key); resJson.put(resKey, changeJsonArr(jsonArr, keyMap)); } catch (Exception x) { 
    resJson.put(resKey, jsonObj.get(key)); } } } return resJson; } / * key的国际化 * * @param jsonArr * @param keyMap * @return */ public static JSONArray changeJsonArr(JSONArray jsonArr, Map<String, String> keyMap) { 
    JSONArray resJson = new JSONArray(); for (int i = 0; i < jsonArr.size(); i++) { 
    JSONObject jsonObj = jsonArr.getJSONObject(i); resJson.add(changeJsonObj(jsonObj, keyMap)); } return resJson; } public static void i18nFormatContentData(List<Map<String, Object>> list) { 
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String locale = request.getHeader("locale"); if (StrUtil.isNotBlank(locale)) { 
    Map<String, String> keyMap = I18nDictionaryCache.getContentDictionary(locale); if (keyMap != null) { 
    list.forEach(x -> { 
    for (Map.Entry<String, Object> valueEntry : x.entrySet()) { 
    if (null != valueEntry.getValue()) { 
    for (Map.Entry<String, String> dictEntry : keyMap.entrySet()) { 
    String value = valueEntry.getValue().toString(); if (value.contains(dictEntry.getKey()) && dictEntry.getValue() != null) { 
    value = value.replace(dictEntry.getKey(), dictEntry.getValue()); x.put(valueEntry.getKey(), value); } } } } }); } } } public static String i18nFormatStringValue(String value) { 
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String locale = request.getHeader("locale"); if (StrUtil.isNotBlank(locale)) { 
    Map<String, String> keyMap = I18nDictionaryCache.getContentDictionary(locale); for (Map.Entry<String, String> dictEntry : keyMap.entrySet()) { 
    if (value.contains(dictEntry.getKey())&&dictEntry.getValue()!=null) { 
    value = value.replaceAll(dictEntry.getKey(), dictEntry.getValue()); } } } return value; } / * 其他语言 转换中文 * @return */ public static String i18nTransChinese(String value){ 
    HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String locale = request.getHeader("locale"); if (StrUtil.isNotBlank(locale)) { 
    Map<String, String> keyMap = I18nDictionaryCache.getTransChineseDict(locale); for (Map.Entry<String, String> dictEntry : keyMap.entrySet()) { 
    if (value.equals(dictEntry.getKey())&&dictEntry.getValue()!=null) { 
    value = dictEntry.getValue(); } } } return value; } 

7.测试代码

讯享网@RestController @RequestMapping("/user") public class I18nController { 
    @RequestMapping("/getInfo") public RetObj<User> getUserInfo(){ 
    RetObj<User> ret=new RetObj<>(); User user = new User("汤姆", 23, "中国", "男"); ret.setMsg("成功"); ret.setObj(user); return ret; } } 

未设置国际化标识

未设置header

设置国际化标识之后

设置header

至此结束!!!

小讯
上一篇 2025-03-28 09:16
下一篇 2025-02-21 09:33

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/33953.html