我正在尝试本地化项目中每个API响应中的几乎每个参数。
我已经发现我们可以在春季启动中做这样的事情:
MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource, locale);
return accessor.getMessage(code);
并将代码与本地化消息映射保留在messages_en.properties
、messages_fr.properties
等中。
但是对于我的应用程序,我特别有两个要求:
- 我想将此逻辑与我的业务逻辑分开,即我不想在每个控制器中编写本地化逻辑。 我想在通过
- 服务器的所有响应的每个响应参数上尝试它,也许在杰克逊将对象转换为字符串或转换为 JSON 后。
在 Spring 启动中是否有办法实现这一点,或者是否有任何可用的库?
我已经找到了解决方案。我没有对字段使用 String,而是使用自定义类,例如 LocalizedText
:
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class LocalizedText {
private String text;
}
对于序列化,我创建了一个 反序列化程序 LocalizedTextSerailizer
,如下所示:
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
@Component
public class LocalizedTextSerializer extends StdSerializer<LocalizedText> {
private static final long serialVersionUID = 619043384446863988L;
@Autowired
I18nUtil messages;
public LocalizedTextSerializer() {
super(LocalizedText.class);
}
public LocalizedTextSerializer(Class<LocalizedText> t) {
super(t);
}
@Override
public void serialize(LocalizedText value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeString(messages.get(value.getText()));
}
}
I18nUtil
:
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class I18nUtil {
@Autowired
private MessageSource messageSource;
public String get(String code) {
try {
MessageSourceAccessor accessor = new MessageSourceAccessor(messageSource, Locale.getDefault());
return accessor.getMessage(code);
} catch (NoSuchMessageException nsme) {
log.info("Message not found in localization: " + code);
return code;
}
}
}
这几乎可以达到目的,我不必弄乱业务逻辑,我可以本地化应用程序中任何响应的任何参数。
注意:
- 在这里,I18nUtil 返回相同的代码,如果它在 message.properties 中找不到任何消息。
- 默认区域设置在 I18nUtil 中使用,用于演示。