Enum 声明字段含义,优雅处理多语言,支持灵活添加

主题

Enum 声明字段含义,优雅处理多语言,支持灵活添加

设计

  • 通过枚举定义字段
  • 定义一个配置文件,定义实现的语言
  • 分别为每种语言配置一套语言翻译,这里利用 Java Resource Bundle 机制

代码依赖

  • JDK 5+
  • JUnit 4
  • fastjson 1.2.66(非必须,仅用在 JUnit 测试中)
  • slf4j + logback(非必须,仅用在 JUnit 测试中)

代码实现

FieldDescEnum

package enumsdemo;

import java.util.Map;

/**
* @author Helly Guo
* <p>
* Created on 3/1/20 12:12 PM
*/
public enum FieldDescEnum {
/**
* XXX
*/
FIELD_X("xxx"),
/**
* YYY
*/
FIELD_Y("yyy"),
/**
* ZZZ
*/
FIELD_Z("zzz");

private final String fieldName;
private final Map<String, String> descLocales;

FieldDescEnum(String fieldName) {
this.fieldName = fieldName;
this.descLocales = FieldDescPropsUtil.getDescriptionByKey(fieldName);
}

public String getFieldName() {
return fieldName;
}

public Map<String, String> getDescLocales() {
return descLocales;
}
}

FieldDescPropsUtil

package enumsdemo;

import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;

/**
* @author Helly Guo
* <p>
* Created on 3/1/20 12:12 PM
*/
public final class FieldDescPropsUtil {
private static final String SUPPORTED_LOCALES_FILE = "support_locales.properties";
private static final String LOCALES = "locales";
private static final String FIELD_DESC = "fieldDesc";

private static final Properties SUPPORTED_LOCALES = new Properties();
private static final Map<String, ResourceBundle> FIELD_DESC_MAP = new HashMap<>();

static {
try {
SUPPORTED_LOCALES.load(FieldDescPropsUtil.class.getClassLoader().getResourceAsStream(SUPPORTED_LOCALES_FILE));
} catch (IOException e) {
throw new RuntimeException("load file failed", e);
}
String localesOneLine = SUPPORTED_LOCALES.getProperty(LOCALES);
String[] locales = localesOneLine.split(",");
String[] langAndCountry;
for (String locale : locales) {
if (locale.indexOf('_') > 0) {
langAndCountry = locale.split("_");
FIELD_DESC_MAP.put(locale,
ResourceBundle.getBundle(FIELD_DESC,
new Locale(langAndCountry[0], langAndCountry[1])));
} else {
FIELD_DESC_MAP.put(locale,
ResourceBundle.getBundle(FIELD_DESC, new Locale(locale)));
}
}
}

private static String getDescriptionByLocale(String key, String locale) {
if (FIELD_DESC_MAP.containsKey(locale)) {
return FIELD_DESC_MAP.get(locale).getString(key);
} else {
return key;
}
}

static Map<String, String> getDescriptionByKey(String key) {
HashMap<String, String> descMap = new HashMap<>();
for (String locale : FIELD_DESC_MAP.keySet()) {
descMap.put(locale, getDescriptionByLocale(key, locale));
}
return descMap;
}
}

support_locales.properties

locales=zh_CN,en_US

fieldDesc.properties

xxx=xxx
yyy=yyy
zzz=zzz

fieldDesc_en_US.properties

xxx=x!x!x!
yyy=y!y!y!
zzz=z!z!z!

filedDesc_zh_CN.properties

xxx=未知X!
yyy=未知Y!
zzz=未知Z!

单元测试

FieldDescEnumTest.java

package enumsdemo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Helly Guo
* <p>
* Created on 3/1/20 1:59 PM
*/
public class FieldDescEnumTest {
private static final Logger LOGGER = LoggerFactory.getLogger(FieldDescEnumTest.class);

@Test
public void test() {
SerializeConfig config = new SerializeConfig();
config.configEnumAsJavaBean(FieldDescEnum.class);
LOGGER.info(JSON.toJSONString(FieldDescEnum.FIELD_X, config));
LOGGER.info(JSON.toJSONString(FieldDescEnum.FIELD_Y, config));
LOGGER.info(JSON.toJSONString(FieldDescEnum.FIELD_Z, config));
}

}